📄 api+protocol
字号:
result of the permissions on a object changing, or an object being deleted. There should never be a response to this message.internals:Both client and server use same protocol and infrastructure. Thereare many object types, each of which is stored in a registry.Objects whose type is not recognized can either be handled by thegeneric object type, which is registered with the type "*". If nogeneric object type is registered, then objects with unknown types aresimply not supported. On the client, there are probably no specialobject handlers (although this is by no means forbidden). On theserver, probably everything is a special object.Each object type has the following methods:dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection, char *server_name, int port, dhcpctl_handle *authinfo) synchronous returns nonzero status code if it didn't connect, zero otherwise stores connection handle through connection, which can be used for subsequent access to the specified server. server_name is the name of the server, and port is the TCP port on which it is listening. authinfo is the handle to an object containing authentication information.dhcpctl_status dhcpctl_open_object (dhcpctl_handle h, dhcpctl_handle connection, int flags) asynchronous - just queues the request returns nonzero status code if open couldn't be queued returns zero if open was queued h is a handle to an object created by dhcpctl_new_object connection is a connection to a DHCP server flags include: DHCPCTL_CREATE - if the object doesn't exist, create it DHCPCTL_UPDATE - update the object on the server using the attached parameters DHCPCTL_EXCL - error if the object exists and DHCPCTL_CREATE was also specifieddhcpctl_status dhcpctl_new_object (dhcpctl_handle *h, dhcpctl_handle connection, char *object_type) synchronous - creates a local handle for a host entry. returns nonzero status code if the local host entry couldn't be created stores handle to host through h if successful, and returns zero. object_type is a pointer to a NUL-terminated string containing the ascii name of the type of object being accessed - e.g., "host"dhcpctl_status dhcpctl_set_callback (dhcpctl_handle h, void *data, void (*callback) (dhcpctl_handle, dhcpctl_status, void *)) synchronous, with asynchronous aftereffect handle is some object upon which some kind of process has been started - e.g., an open, an update or a refresh. data is an anonymous pointer containing some information that the callback will use to figure out what event completed. return value of 0 means callback was successfully set, a nonzero status code is returned otherwise. Upon completion of whatever task is in process, the callback will be passed the handle to the object, a status code indicating what happened, and the anonymous pointer passed to dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h, dhcpctl_status *s) synchronous returns zero if the callback completes, a nonzero status if there was some problem relating to the wait operation. The status of the queued request will be stored through s, and will also be either zero for success or nonzero for some kind of failure. Never returns until completion or until the connection to the server is lost. This performs the same function as dhcpctl_set_callback and the subsequent callback, for programs that want to do inline execution instead of using callbacks.dhcpctl_status dhcpctl_get_value (data_string *result, dhcpctl_handle h, char *value_name) synchronous returns zero if the call succeeded, a nonzero status code if it didn't. result is the address of an empty data string (initialized with bzero or cleared with data_string_forget). On successful completion, the addressed data string will contain the value that was fetched. dhcpctl_handle refers to some dhcpctl item value_name refers to some value related to that item - e.g., for a handle associated with a completed host lookup, value could be one of "hardware-address", "dhcp-client-identifier", "known" or "client-hostname".dhcpctl_status dhcpctl_get_boolean (int *result, dhcpctl_handle h, char *value_name) like dhcpctl_get_value, but more convenient for boolean values, since no data_string needs to be dealt with.dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, data_string value, char *value_name) Sets a value on an object referred to by a dhcpctl_handle. The opposite of dhcpctl_get_value. Does not update the server - just sets the value on the handle.dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, char *value, char *value_name) Sets a NUL-terminated ASCII value on an object referred to by a dhcpctl_handle. like dhcpctl_set_value, but saves the trouble of creating a data_string for a NUL-terminated string. Does not update the server - just sets the value on the handle.dhcpctl_status dhcpctl_set_boolean (dhcpctl_handle h, int value, char *value_name) Sets a boolean value on an object - like dhcpctl_set_value, only more convenient for booleans.dhcpctl_status dhcpctl_object_update (dhcpctl_handle h) Queues an update on the object referenced by the handle (there can't be any other work in progress on the handle). An update means local parameters will be sent to the server.dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle h) Queues an update on the object referenced by the handle (there can't be any other work in progress on the handle). An update means local parameters will be sent to the server.dhcpctl_status dhcpctl_object_delete (dhcpctl_handle h) Queues a delete of the object referenced by the handle (there can't be any other work in progress on the handle). A delete means that the object will be permanently deleted on the remote end, assuming the remote end supports object persistence.So a sample program that would update a host declaration would looksomething like this: /* Create a local object into which to store authentication information. */ if ((status = dhcpctl_new_object (&auth, dhcpctl_null_handle, "authentication-information"))) dhcpctl_error ("Can't create authentication information: %m"); /* Set up the authenticator with an algorithm type, user name and password. */ if ((status = dhcpctl_set_string_value (&auth, "mellon", "username"))) dhcpctl_error ("Can't set username: %m", status); if ((status = dhcpctl_set_string_value (&auth, "three blind mice", "password"))) dhcpctl_error ("Can't set password: %m", status); if ((status = dhcpctl_set_string_value (&auth, "md5-hash", "algorithm"))) dhcpctl_error ("Can't set authentication algorithm: %m.", status); /* Connect to the server. */ if ((status = dhcpctl_connect (&c, "dhcp.server.com", 612, &auth))) dhcpctl_error ("Can't connect to dhcp.server.com: %m", status); /* Create a host object. */ if ((status = dhcpctl_new_object (&hp, c, "host"))) dhcpctl_error ("Host create failed: %m", status); /* Create a data_string to contain the host's client identifier, and set it. */ if ((status = data_string_create_from_hex (&client_id, "1:08:00:2b:34:1a:c3"))) dhcpctl_error ("Can't create client identifier: %m"); if ((status = dhcpctl_set_value (hp, client_id, "dhcp-client-identifier"))) dhcpctl_error ("Host client identifier set failed."); /* Set the known flag to 1. */ if ((status = dhcpctl_set_boolean (hp, 1, "known"))) dhcpctl_error ("Host known set failed."); /* Open an existing host object that matches the client identifier, and update it from the local context, or if no host entry yet exists matching the identifier, create one and initialize it. */ if ((status = dhcpctl_open_object (&hp, c, DHCPCTL_CREATE | DHCPCTL_UPDATE))) dhcpctl_error ("Can't open host: %m", status); /* Wait for the process to complete, check status. */ if ((status = dhcpctl_wait_for_completion (hp, &wait_status))) dhcpctl_error ("Host create/lookup wait failed: %m", status); if (waitstatus) dhcpctl_error ("Host create/lookup failed: %m", status);The API is a bit complicated, for a couple of reasons. I want tomake it general, so that there aren't a bazillion functions to call,one for each data type. I want it to be thread-safe, which is whyeach function returns a status and the error printer requires a statuscode for input. I want it to be possible to make it asynchronous, sothat it can work in tandem with, for example, an X toolkit. Ifyou're just writing a simple update cgi program, you probably won'twant to bother to use the asynchronous callbacks, and indeed the aboveexample doesn't.I glossed over data strings above - basically, they're objects with apointer to a reference-counted buffer structure, an offset into thatbuffer, and a length. These are used within the DHCP server, so youcan get an idea of how they work - basically, they're a convenient andefficient way to store a string with a length such that substrings caneasily be taken and such that more than one user at a time can have apointer to the string.I will also probably add locking primitives, so that you can get thevalue of something and be sure that some other updator process won'tmodify it while you have the lock.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -