/**
* @defgroup tsocket The tsocket API
*
- * The tsocket abstraction is splitted into two different kinds of
- * communitation interfaces.
+ * The tsocket abstraction is split into two different kinds of
+ * communication interfaces.
*
* There's the "tstream_context" interface with abstracts the communication
* through a bidirectional byte stream between two endpoints.
* @section vsock Virtual Sockets
*
* The abstracted layout of tdgram_context and tstream_context allow
- * implementations arround virtual sockets for encrypted tunnels (like TLS,
+ * implementations around virtual sockets for encrypted tunnels (like TLS,
* SASL or GSSAPI) or named pipes over smb.
*
* @section npa Named Pipe Auth (NPA) Sockets
*/
/**
- * @brief Get a string representaion of the endpoint.
+ * @brief Get a string representation of the endpoint.
*
* This function creates a string representation of the endpoint for debugging.
* The output will look as followed:
*
* @return The address as a string representation, NULL on error.
*
+ * @see tsocket_address_is_inet()
* @see tsocket_address_inet_addr_string()
* @see tsocket_address_inet_port()
*/
*
* @param[in] req The tevent request from tdgram_recvfrom_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @param[in] mem_ctx The memory context to use.
*
*
* @param[in] req The tevent request from tdgram_sendto_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @return The length of the datagram (0 is never returned!), -1 on
* error with perrno set to the actual errno.
*
* @param[in] req The tevent request from tdgram_disconnect_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @return The length of the datagram (0 is never returned!), -1 on
* error with perrno set to the actual errno.
*
* @param[in] req The tevent request from tstream_readv_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @return The length of the stream (0 is never returned!), -1 on
* error with perrno set to the actual errno.
*
* @param[in] req The tevent request from tstream_writev_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @return The length of the stream (0 is never returned!), -1 on
* error with perrno set to the actual errno.
*
* @param[in] req The tevent request from tstream_disconnect_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @return The length of the stream (0 is never returned!), -1 on
* error with perrno set to the actual errno.
* @{
*/
+/**
+ * @brief Find out if the tsocket_address represents an ipv4 or ipv6 endpoint.
+ *
+ * @param[in] addr The tsocket_address pointer
+ *
+ * @param[in] fam The family can be can be "ipv4", "ipv6" or "ip". With
+ * "ip" is autodetects "ipv4" or "ipv6" based on the
+ * addr.
+ *
+ * @return true if addr represents an address of the given family,
+ * otherwise false.
+ */
+bool tsocket_address_is_inet(const struct tsocket_address *addr, const char *fam);
+
#if DOXYGEN
/**
* @brief Create a tsocket_address for ipv4 and ipv6 endpoint addresses.
*
* @return A newly allocated string of the address, NULL on error
* with errno set.
+ *
+ * @see tsocket_address_is_inet()
*/
char *tsocket_address_inet_addr_string(const struct tsocket_address *addr,
TALLOC_CTX *mem_ctx);
int tsocket_address_inet_set_port(struct tsocket_address *addr,
uint16_t port);
+/**
+ * @brief Find out if the tsocket_address represents an unix domain endpoint.
+ *
+ * @param[in] addr The tsocket_address pointer
+ *
+ * @return true if addr represents an unix domain endpoint,
+ * otherwise false.
+ */
+bool tsocket_address_is_unix(const struct tsocket_address *addr);
+
#ifdef DOXYGEN
/**
* @brief Create a tsocket_address for a unix domain endpoint addresses.
* @param[in] _addr The tsocket_address pointer to store the information.
*
* @return 0 on success, -1 on error with errno set.
+ *
+ * @see tsocket_address_is_unix()
*/
int tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
const char *path,
char *tsocket_address_unix_path(const struct tsocket_address *addr,
TALLOC_CTX *mem_ctx);
+#ifdef DOXYGEN
+/**
+ * @brief Wrap an existing file descriptors into the tdgram abstraction.
+ *
+ * You can use this function to wrap an existing file descriptors into the
+ * tdgram abstraction. After that you're not able to use this file descriptor
+ * for anything else. The file descriptor will be closed when the stream gets
+ * freed. If you still want to use the fd you have have to create a duplicate.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] fd The non blocking fd to use!
+ *
+ * @param[out] dgram A pointer to store an allocated tdgram_context.
+ *
+ * @return 0 on success, -1 on error.
+ *
+ * Example:
+ * @code
+ * fd2 = dup(fd);
+ * rc = tdgram_bsd_existing_socket(mem_ctx, fd2, &tdgram);
+ * if (rc < 0) {
+ * return;
+ * }
+ * @endcode
+ *
+ * @warning This is an internal function. You should read the code to fully
+ * understand it if you plan to use it.
+ */
+int tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx,
+ int fd,
+ struct tdgram_context **dgram);
+#else
+int _tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx,
+ int fd,
+ struct tdgram_context **_dgram,
+ const char *location);
+#define tdgram_bsd_existing_socket(mem_ctx, fd, dgram) \
+ _tdgram_bsd_existing_socket(mem_ctx, fd, dgram, \
+ __location__)
+#endif
+
+/**
+ * @brief Request a syscall optimization for tdgram_recvfrom_send()
+ *
+ * This function is only used to reduce the amount of syscalls and
+ * optimize performance. You should only use this if you know
+ * what you're doing.
+ *
+ * The optimization is off by default.
+ *
+ * @param[in] dgram The tdgram_context of a bsd socket, if this
+ * not a bsd socket the function does nothing.
+ *
+ * @param[in] on The boolean value to turn the optimization on and off.
+ *
+ * @return The old boolean value.
+ *
+ * @see tdgram_recvfrom_send()
+ */
+bool tdgram_bsd_optimize_recvfrom(struct tdgram_context *dgram,
+ bool on);
+
#ifdef DOXYGEN
/**
* @brief Create a tdgram_context for a ipv4 or ipv6 UDP communication.
* communication. The function will allocate the memory.
*
* @return 0 on success, -1 on error with errno set.
+ *
+ * @see tdgram_inet_udp_broadcast_socket()
*/
int tdgram_inet_udp_socket(const struct tsocket_address *local,
const struct tsocket_address *remote,
_tdgram_inet_udp_socket(local, remote, mem_ctx, dgram, __location__)
#endif
+#ifdef DOXYGEN
+/**
+ * @brief Create a tdgram_context for a ipv4 UDP broadcast (and unicast) communication.
+ *
+ * @param[in] local An 'inet' (ipv4 only) tsocket_address for the local endpoint.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] dgram The tdgram_context pointer to setup the udp
+ * communication. The function will allocate the memory.
+ *
+ * @return 0 on success, -1 on error with errno set.
+ *
+ * @see tdgram_inet_udp_socket()
+ */
+int tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local,
+ TALLOC_CTX *mem_ctx,
+ struct tdgram_context **dgram);
+#else
+int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local,
+ TALLOC_CTX *mem_ctx,
+ struct tdgram_context **dgram,
+ const char *location);
+#define tdgram_inet_udp_broadcast_socket(local, mem_ctx, dgram) \
+ _tdgram_inet_udp_broadcast_socket(local, mem_ctx, dgram, __location__)
+#endif
+
#ifdef DOXYGEN
/**
* @brief Create a tdgram_context for unix domain datagram communication.
_tdgram_unix_socket(local, remote, mem_ctx, dgram, __location__)
#endif
+/**
+ * @brief Request a syscall optimization for tstream_readv_send()
+ *
+ * This function is only used to reduce the amount of syscalls and
+ * optimize performance. You should only use this if you know
+ * what you're doing.
+ *
+ * The optimization is off by default.
+ *
+ * @param[in] stream The tstream_context of a bsd socket, if this
+ * not a bsd socket the function does nothing.
+ *
+ * @param[in] on The boolean value to turn the optimization on and off.
+ *
+ * @return The old boolean value.
+ *
+ * @see tstream_readv_send()
+ */
+bool tstream_bsd_optimize_readv(struct tstream_context *stream,
+ bool on);
+
/**
* @brief Connect async to a TCP endpoint and create a tstream_context for the
* stream based communication.
*
* @param[in] req The tevent request from tstream_inet_tcp_connect_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @param[in] mem_ctx The talloc memory context to use.
*
- * @param[in] stream A tstream_context pointer to setup the tcp communication
+ * @param[out] stream A tstream_context pointer to setup the tcp communication
* on. This function will allocate the memory.
*
+ * @param[out] local The real 'inet' tsocket_address of the local endpoint.
+ * This parameter is optional and can be NULL.
+ *
* @return 0 on success, -1 on error with perrno set.
*/
int tstream_inet_tcp_connect_recv(struct tevent_req *req,
int *perrno,
TALLOC_CTX *mem_ctx,
- struct tstream_context **stream);
+ struct tstream_context **stream,
+ struct tsocket_address **local)
#else
int _tstream_inet_tcp_connect_recv(struct tevent_req *req,
int *perrno,
TALLOC_CTX *mem_ctx,
struct tstream_context **stream,
+ struct tsocket_address **local,
const char *location);
-#define tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream) \
- _tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream, \
+#define tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream, local) \
+ _tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream, local, \
__location__)
#endif
*
* @param[in] req The tevent request from tstream_inet_tcp_connect_send().
*
- * @param[out] perrno The error number, set if an error occured.
+ * @param[out] perrno The error number, set if an error occurred.
*
* @param[in] mem_ctx The talloc memory context to use.
*
* @return 0 on success, -1 on error with errno set.
*/
int tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
- struct sockaddr *sa,
+ const struct sockaddr *sa,
size_t sa_socklen,
struct tsocket_address **addr);
#else
int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
- struct sockaddr *sa,
+ const struct sockaddr *sa,
size_t sa_socklen,
struct tsocket_address **_addr,
const char *location);
* @brief Wrap an existing file descriptors into the tstream abstraction.
*
* You can use this function to wrap an existing file descriptors into the
- * tstream abstraction.
+ * tstream abstraction. After that you're not able to use this file descriptor
+ * for anything else. The file descriptor will be closed when the stream gets
+ * freed. If you still want to use the fd you have have to create a duplicate.
*
- * @param[in] mem_ctx The talloc memory context to use.
+ * @param[in] mem_ctx The talloc memory context to use.
*
- * @param[in] fd The non blocking fd to use!
+ * @param[in] fd The non blocking fd to use!
*
- * @param[in] stream The filed tstream_context you allocated before.
+ * @param[out] stream A pointer to store an allocated tstream_context.
*
- * @return 0 on success, -1 on error with errno set.
+ * @return 0 on success, -1 on error.
*
- * @warning You should read the tsocket_bsd.c code and unterstand it in order
- * use this function.
+ * Example:
+ * @code
+ * fd2 = dup(fd);
+ * rc = tstream_bsd_existing_socket(mem_ctx, fd2, &tstream);
+ * if (rc < 0) {
+ * stream_terminate_connection(conn, "named_pipe_accept: out of memory");
+ * return;
+ * }
+ * @endcode
+ *
+ * @warning This is an internal function. You should read the code to fully
+ * understand it if you plan to use it.
*/
int tstream_bsd_existing_socket(TALLOC_CTX *mem_ctx,
int fd,
* delivered to the underlying system socket.
*
* The caller needs to make sure that all non-scalar input parameters hang
- * arround for the whole lifetime of the request.
+ * around for the whole lifetime of the request.
*
* @param[in] mem_ctx The memory context for the result.
*
int tstream_readv_pdu_recv(struct tevent_req *req, int *perrno);
/**
- * @brief Queue a dgram blob for sending through the socket.
+ * @brief Queue a read request for a PDU on the socket.
*
- * This function queues a blob for sending to destination through an existing
- * dgram socket. The async callback is triggered when the whole blob is
- * delivered to the underlying system socket.
+ * This function queues a read request for a PDU on a stream socket. The async
+ * callback is triggered when a full PDU has been read from the socket.
*
* The caller needs to make sure that all non-scalar input parameters hang
- * arround for the whole lifetime of the request.
+ * around for the whole lifetime of the request.
*
* @param[in] mem_ctx The memory context for the result
*
void *next_vector_private);
/**
- * @brief Receive the result of the sent dgram blob.
+ * @brief Receive the PDU blob read from the stream.
*
* @param[in] req The tevent request from tstream_readv_pdu_queue_send().
*
* @param[out] perrno The error set to the actual errno.
*
- * @return The length of the datagram (0 is never returned!), -1 on
- * error with perrno set to the actual errno.
+ * @return The number of bytes read on success, -1 on error with
+ * perrno set to the actual errno.
*/
int tstream_readv_pdu_queue_recv(struct tevent_req *req, int *perrno);
/**
- * @brief Queue a dgram blob for sending through the socket
+ * @brief Queue an iovector for sending through the socket
*
- * This function queues a blob for sending to destination through an existing
- * dgram socket. The async callback is triggered when the whole blob is
- * delivered to the underlying system socket.
+ * This function queues an iovector for sending to destination through an
+ * existing stream socket. The async callback is triggered when the whole
+ * vectror has been delivered to the underlying system socket.
*
* The caller needs to make sure that all non-scalar input parameters hang
- * arround for the whole lifetime of the request.
+ * around for the whole lifetime of the request.
*
* @param[in] mem_ctx The memory context for the result.
*
size_t count);
/**
- * @brief Receive the result of the sent dgram blob.
+ * @brief Receive the result of the sent iovector.
*
* @param[in] req The tevent request from tstream_writev_queue_send().
*
* @param[out] perrno The error set to the actual errno.
*
- * @return The length of the datagram (0 is never returned!), -1 on
+ * @return The length of the iovector (0 is never returned!), -1 on
* error with perrno set to the actual errno.
*/
int tstream_writev_queue_recv(struct tevent_req *req, int *perrno);