00001 /** 00002 @mainpage 00003 00004 @section intro Introduction 00005 00006 libafdt is a library for "a"synchronous "f"ile "d"escriptor "t"ransfers. 00007 It provides a simple interface that allows libevent-based programs to 00008 set up a Unix domain socket to accept connections and transfer file 00009 descriptors to clients, or to be a client and request a file descriptor 00010 from a libafdt server. Low-level and synchronous interfaces are also 00011 provided for programs that do not use libevent. 00012 00013 See <em>Advanced Programming in the UNIX(R) Environment</em> for more 00014 information about transferring file descriptors between processes using 00015 Unix domain sockets. 00016 00017 @section structure Structure 00018 00019 libafdt's has two high-level interfaces: an \link async Asynchronous 00020 Interface \endlink and a \link sync Synchronous Interface \endlink . 00021 The former is best for clients or servers that are based on libevent. 00022 It uses callbacks to allow the program to process high-level events. 00023 The latter is for clients that don't use libevent and are willing to 00024 block while waiting to receive a response. It does not require 00025 libevent, and is much more convenient when blocking is acceptable. 00026 00027 There is also a \link lowlevel Low-level Interface \endlink . It does 00028 not require libevent, but can still be used without blocking. It can 00029 also be used to change the simple protocol used by the high-level 00030 interfaces. It requires a bit more bookkeeping to use. 00031 00032 @section examples Examples 00033 00034 The test programs are good examples of how to use the high-level 00035 interfaces. 00036 00037 The high-level interfaces are good examples of how to use the low-level 00038 interface. 00039 */ 00040 00041 /** 00042 @file 00043 @brief The main header file for libafdt 00044 00045 This file contains all of the types and functions available in 00046 the libafdt API. All other files are for internal use only. 00047 */ 00048 00049 #ifndef _AFDT_H 00050 #define _AFDT_H 00051 00052 // Put this in an ifndef so it doesn't go into the generated man page. 00053 #ifndef DOXYGEN 00054 #include <stdint.h> 00055 #endif 00056 00057 #ifdef __cplusplus 00058 extern "C" { 00059 #endif 00060 00061 00062 /** 00063 * @brief Maximum request or response message length, including the header. 00064 * 00065 * This is relatively small so that we can consider short reads writes to be 00066 * exceptional circumstances, rather than business as usual. 00067 */ 00068 #define AFDT_FULL_MSGLEN 0x200 00069 00070 /** 00071 * @brief Maximum request or response message length, excluding the header. 00072 */ 00073 #define AFDT_MSGLEN (AFDT_FULL_MSGLEN - sizeof(uint32_t)) 00074 00075 00076 // Declare these as incomplete types. 00077 // The appropriate headers need to be included in order to use them. 00078 struct event_base; 00079 struct timeval; 00080 00081 00082 /** 00083 @defgroup errors Error Handling 00084 00085 Types, values, and functions used for reporting errors. 00086 */ 00087 00088 /** 00089 * @ingroup errors 00090 * @brief Phase of the AFDT process during which an error occurred. 00091 * 00092 * These error codes are used by the asynchronous interface to indicate 00093 * the high-level operation that triggered an error. 00094 */ 00095 enum afdt_phase { 00096 AFDT_NO_PHASE, 00097 AFDT_CREATE_SERVER, 00098 AFDT_ACCEPT_CLIENT, 00099 AFDT_HANDLE_REQUEST, 00100 AFDT_CREATE_CLIENT, 00101 AFDT_HANDLE_RESPONSE, 00102 }; 00103 00104 /** 00105 * @ingroup errors 00106 * @brief Operation that resulted in an error. 00107 * 00108 * These error codes are used by the all interfaces to indicate the low-level 00109 * operation that triggered an error. These are mostly system calls. 00110 */ 00111 enum afdt_operation { 00112 AFDT_NO_OPERATION, 00113 AFDT_MALLOC, 00114 AFDT_SOCKET, 00115 AFDT_PATHNAME, 00116 AFDT_BIND, 00117 AFDT_LISTEN, 00118 AFDT_ACCEPT, 00119 AFDT_CONNECT, 00120 AFDT_FORMAT, 00121 AFDT_SENDMSG, 00122 AFDT_RECVMSG, 00123 AFDT_EVENT_BASE_SET, 00124 AFDT_EVENT_ADD, 00125 AFDT_POLL, 00126 AFDT_TIMEOUT, 00127 }; 00128 00129 /** 00130 * @ingroup errors 00131 * @brief Detailed information about an error. 00132 */ 00133 struct afdt_error_t { 00134 /// @brief High-level phase during which the error occurred. 00135 enum afdt_phase phase; 00136 /// @brief Low-level operation that caused the error. 00137 enum afdt_operation operation; 00138 /// @brief Additional human-readable information, or "". 00139 const char* message; 00140 }; 00141 00142 /** 00143 * @ingroup errors 00144 * @brief Initializer for error information. 00145 * 00146 * All \c afdt_error_t objects passed to functions in the low-level interface 00147 * should be initialized with this value. 00148 */ 00149 extern const struct afdt_error_t AFDT_ERROR_T_INIT; 00150 00151 /** 00152 * @ingroup errors 00153 * @brief Convert \c afdt_phase into a textual description. 00154 */ 00155 const char* afdt_phase_str(enum afdt_phase phase); 00156 00157 /** 00158 * @ingroup errors 00159 * @brief Convert \c afdt_operation into a textual description. 00160 */ 00161 const char* afdt_operation_str(enum afdt_operation operation); 00162 00163 00164 /** 00165 @defgroup lowlevel Low-level Interface 00166 00167 The low-level interface provides a thin abstraction over the 00168 primitives used for transferring file descriptors over Unix domain 00169 sockets. The higher-level interfaces are implemented in terms of 00170 these functions, which can also be used to implement a high-level 00171 interface on top of a different event loop API or a high-level 00172 interface obeying a different protocol (for example: the client 00173 sending the file descriptor to the server). 00174 00175 This layer imposes very few restrictions on usage. Messages must 00176 be at most AFDT_MSGLEN bytes, and are automatically prefixed with 00177 a 32-bit host-byte-order header equal to the message length. 00178 At most one one file descriptor can be passed per message. 00179 00180 The most interesting operation provided by this interface is 00181 send/recv fd_msg, which is a short message and an optional 00182 file descriptor. Functions are also provided for sending and 00183 receiving "plain" messages, which do not include file descriptors. 00184 00185 All functions in this interface report errors by returning a negative 00186 value and populating detailed information into their \a err parameter. 00187 (\a err should be initialized to \c AFDT_ERROR_T_INIT.) errno will 00188 be set to an appropriate code, or 0 if no error code is applicable. 00189 */ 00190 00191 /** 00192 * @ingroup lowlevel 00193 * @brief Create a socket that listens for connections. 00194 * 00195 * Higher level code should call \c accept(2) on the returned socket 00196 * to accept a connection from a client. 00197 * 00198 * @param fname File to bind PF_LOCAL socket to. 00199 * @param err Structure to populate with error information. 00200 * 00201 * @return socket fd (>=0) if successful, <0 on failure. 00202 */ 00203 int afdt_listen(const char* fname, struct afdt_error_t* err); 00204 00205 /** 00206 * @ingroup lowlevel 00207 * @brief Create a socket and connect to a listening socket. 00208 * 00209 * @param fname File to connect PF_LOCAL socket to. 00210 * @param err Structure to populate with error information. 00211 * 00212 * @return socket fd (>=0) if successful, <0 on failure. 00213 */ 00214 int afdt_connect(const char* fname, struct afdt_error_t* err); 00215 00216 /** 00217 * @ingroup lowlevel 00218 * @brief Send a message with an optional file descriptor. 00219 * 00220 * @param connfd Descriptor from \c accept or \c afdt_connect. 00221 * @param content Message content. 00222 * @param content_len Message length. 00223 * @param fd_to_send File descriptor to send, or <0 for none. 00224 * @param err Structure to populate with error information. 00225 * 00226 * @return >=0 if successful, <0 on failure. 00227 */ 00228 int afdt_send_fd_msg( 00229 int connfd, 00230 const uint8_t* content, 00231 uint32_t content_len, 00232 int fd_to_send, 00233 struct afdt_error_t* err); 00234 00235 /** 00236 * @ingroup lowlevel 00237 * @brief Send a message with no file descriptor. 00238 * @see afdt_send_fd_msg 00239 */ 00240 int afdt_send_plain_msg( 00241 int connfd, 00242 const uint8_t* content, 00243 uint32_t content_len, 00244 struct afdt_error_t* err); 00245 00246 /** 00247 * @ingroup lowlevel 00248 * @brief Receive a message with an optional file descriptor. 00249 * 00250 * @param connfd Descriptor from \c accept or \c afdt_connect. 00251 * @param content Buffer for message content. 00252 * @param content_len Pointer to buffer length, returns with actual length. 00253 * @param received_fd Returns with received fd, or <0 if none. 00254 * @param err Structure to populate with error information. 00255 * 00256 * @return >=0 if successful, <0 on failure. 00257 */ 00258 int afdt_recv_fd_msg( 00259 int connfd, 00260 uint8_t* content, 00261 uint32_t* content_len, 00262 int *received_fd, 00263 struct afdt_error_t* err); 00264 00265 /** 00266 * @ingroup lowlevel 00267 * @brief Receive a message with no file descriptor. 00268 * @see afdt_recv_fd_msg 00269 */ 00270 int afdt_recv_plain_msg( 00271 int connfd, 00272 uint8_t* content, 00273 uint32_t* content_len, 00274 struct afdt_error_t* err); 00275 00276 00277 /** 00278 @defgroup async Asynchronous Interface (libevent-based) 00279 00280 The asynchronous interface provides functions for setting up clients 00281 and servers that use event-driven I/O to avoid blocking a thread. 00282 libevent is used to make the interface work with many different 00283 event APIs. 00284 00285 The asynchronous interface is adds more restrictions than the 00286 low-level API. Interactions are always composed of two messages: 00287 a plain message from the client to the server (the request) followed 00288 by an fd message from the server to the client(the response). 00289 There is currently no support for a client sending a file descriptor 00290 to the server. (In most cases, it is not too hard to invert the 00291 "client" and "server" roles to get around this. The server is simply 00292 the program that listens on the Unix domain socket.) 00293 00294 Most functions in this interface report errors by calling an error 00295 callback and passing error information to it. errno will be set to 00296 an appropriate code, or 0 if no error code is applicable. 00297 */ 00298 00299 /** 00300 * @ingroup async 00301 * @brief Callback type for processing an AFDT request. 00302 * 00303 * For example, a callback could check some authentication information 00304 * in the request, look in the request for the name of some resource, 00305 * then return the appropriate fd or send an error message in the response. 00306 * Remember to set *\a response_length to 0 if you are sending an empty 00307 * response. 00308 * 00309 * @param request Request buffer sent by the client. 00310 * @param request_length Length of \a request. 00311 * @param response Buffer into which to write the response. 00312 * @param response_length IN/OUT: \a response buffer/content size. 00313 * @param userdata Extra parameter passed to \c create_server. 00314 * @return File descriptor to send, or <0 for none. 00315 */ 00316 typedef int (*afdt_request_handler_t)( 00317 const uint8_t* request, 00318 uint32_t request_length, 00319 uint8_t* response, 00320 uint32_t* response_length, 00321 void *userdata); 00322 00323 /** 00324 * @ingroup async 00325 * @brief Callback type for processing an AFDT response. 00326 * 00327 * For example, a callback could pass the file descriptor to 00328 * \e evhttp_accept_socket and start serving requests, or send another 00329 * request if the response indicates that the transfer was not authorized. 00330 * 00331 * @param response Response buffer sent by the server. 00332 * @param response_length Length of \a response. 00333 * @param received_fd File descriptor received, or <0 for none. 00334 * @param userdata Extra parameter passed to \c create_client. 00335 */ 00336 typedef void (*afdt_response_handler_t)( 00337 const uint8_t* response, 00338 uint32_t response_length, 00339 int received_fd, 00340 void *userdata); 00341 00342 /** 00343 * @ingroup async 00344 * @brief Callback type for after a response is sent. 00345 * 00346 * For example, a callback could close \a sent_fd if the recipient is 00347 * going to take over all operations. 00348 * 00349 * @param request Request buffer sent by the client. 00350 * @param request_length Length of \a request. 00351 * @param response Response buffer sent by the server. 00352 * @param response_length Length of \a response. 00353 * @param received_fd File descriptor sent (by \a request_handler). 00354 * @param userdata Extra parameter passed to \c create_server. 00355 */ 00356 typedef void (*afdt_post_handler_t)( 00357 const uint8_t* request, 00358 uint32_t request_length, 00359 const uint8_t* response, 00360 uint32_t response_length, 00361 int sent_fd, 00362 void *userdata); 00363 00364 /** 00365 * @ingroup async 00366 * @brief Callback type for processing errors during AFDT operations. 00367 * 00368 * For example, a callback could log an error message, then try some 00369 * other means of acquiring the resources it needs. 00370 * 00371 * @param phase AFDT phase during which the error occurred. 00372 * @param operation Operation that resulted in the error. 00373 * @param message Extra information message (often empty). 00374 * @param userdata Extra parameter passed to 00375 * \c create_client or \c create_server. 00376 */ 00377 typedef void (*afdt_error_handler_t)( 00378 const struct afdt_error_t* err, 00379 void *userdata); 00380 00381 /** 00382 * @ingroup async 00383 * @brief No-op function that can be used as a post_handler. 00384 */ 00385 void afdt_no_post( 00386 const uint8_t* request, 00387 uint32_t request_length, 00388 const uint8_t* response, 00389 uint32_t response_length, 00390 int sent_fd, 00391 void *userdata); 00392 00393 /** 00394 * @ingroup async 00395 * @brief Create a server to make file descriptors available. 00396 * 00397 * \a request_handler and \a error_handler may both be called 00398 * multiple times. 00399 * 00400 * @param fname File to bind PF_LOCAL socket to. 00401 * Must not exist. 00402 * @param eb struct event_base to manage this server. 00403 * @param request_handler Callback to handle requests. 00404 * @param post_handler Callback called after sending a response. 00405 * @param error_handler Callback to handle errors. 00406 * @param out_close_handle If non-\c NULL, set to a handle for 00407 * \c afdt_close_server. 00408 * @param userdata Arbitrary value to pass to callbacks. 00409 * @return >=0 if successful, <0 on failure. 00410 * \a error_handler will also be called on failure. 00411 */ 00412 int afdt_create_server( 00413 const char* fname, 00414 struct event_base* eb, 00415 afdt_request_handler_t request_handler, 00416 afdt_post_handler_t post_handler, 00417 afdt_error_handler_t error_handler, 00418 void** out_close_handle, 00419 void* userdata); 00420 00421 /** 00422 * @ingroup async 00423 * @brief Shut down a server created by \c afdt_create_server. 00424 * 00425 * Any client connections that have already been created 00426 * will continue to exist. 00427 * 00428 * @param close_handle Handle provided by \c afdt_create_server. 00429 * @return >=0 if successful, <0 on failure. 00430 */ 00431 int afdt_close_server(void* close_handle); 00432 00433 /** 00434 * @ingroup async 00435 * @brief Request a file descriptor from a server. 00436 * 00437 * Exactly one of \a response_handler and \a error_handler will be called, 00438 * unless timeout is \c NULL and the server never responds. 00439 * 00440 * \note This function currently does a blocking connect and send. 00441 * 00442 * @param fname File to connect PF_LOCAL socket to. 00443 * @param eb struct event_base to manage this client. 00444 * @param request Request buffer to send. 00445 * @param request_length Length of \a request. 00446 * @param response_handler Callback to handle response. 00447 * @param error_handler Callback to handle errors. 00448 * @param timeout Timeout when waiting for response, or \c NULL. 00449 * @param userdata Arbitrary value to pass to callbacks. 00450 * @return >=0 if connection and request successful, <0 on failure. 00451 * \a error_handler will also be called on failure. 00452 */ 00453 int afdt_create_client( 00454 const char* fname, 00455 struct event_base* eb, 00456 const uint8_t* request, 00457 uint32_t request_length, 00458 afdt_response_handler_t response_handler, 00459 afdt_error_handler_t error_handler, 00460 const struct timeval* timeout, 00461 void* userdata); 00462 00463 00464 /** 00465 @defgroup sync Synchronous Client Interface 00466 00467 The synchronous interface provides a very simple function allowing 00468 clients to communicate with servers using the asynchronous interface. 00469 The function is blocking, but supports an optional timeout. 00470 */ 00471 00472 /** 00473 * @ingroup sync 00474 * @brief Request a file descriptor from a server. 00475 * 00476 * @param fname File to connect PF_LOCAL socket to. 00477 * @param request Request buffer to send. 00478 * @param request_length Length of \a request. 00479 * @param response Buffer for response. 00480 * @param response_length Pointer to \a response length, 00481 * returns with actual length. 00482 * @param received_fd Returns with received fd, or <0 if none. 00483 * @param timeout Timeout when waiting for response, or \c NULL. 00484 * @param err Structure to populate with error information. 00485 * @return >=0 if successful, <0 on failure. 00486 */ 00487 int afdt_sync_client( 00488 const char* fname, 00489 const uint8_t* request, 00490 uint32_t request_length, 00491 uint8_t* response, 00492 uint32_t* response_length, 00493 int* received_fd, 00494 const struct timeval* timeout, 00495 struct afdt_error_t* err); 00496 00497 #ifdef __cplusplus 00498 } 00499 #endif 00500 00501 #endif // _AFDT_H