+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup tdgram_context The tdgram_context abstraction
+ * @ingroup tsocket
+ *
+ * The tdgram_context is like an abstract class for datagram based sockets. The
+ * interface provides async 'tevent_req' based functions on top functionality
+ * is similar to the recvfrom(2)/sendto(2)/close(2) syscalls.
+ *
+ * @note You can always use talloc_free(tdgram) to cleanup the resources
+ * of the tdgram_context on a fatal error.
+ * @{
+ */
+
+/**
+ * @brief Ask for next available datagram on the abstracted tdgram_context.
+ *
+ * It returns a 'tevent_req' handle, where the caller can register
+ * a callback with tevent_req_set_callback(). The callback is triggered
+ * when a datagram is available or an error happened.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] dgram The dgram context to work on.
+ *
+ * @return Returns a 'tevent_req' handle, where the caller can
+ * register a callback with tevent_req_set_callback().
+ * NULL on fatal error.
+ *
+ * @see tdgram_inet_udp_socket()
+ * @see tdgram_unix_socket()
+ */
+struct tevent_req *tdgram_recvfrom_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tdgram_context *dgram);
+
+/**
+ * @brief Receive the next available datagram on the abstracted tdgram_context.
+ *
+ * This function should be called by the callback when a datagram is available
+ * or an error happened.
+ *
+ * The caller can only have one outstanding tdgram_recvfrom_send() at a time
+ * otherwise the caller will get '*perrno = EBUSY'.
+ *
+ * @param[in] req The tevent request from tdgram_recvfrom_send().
+ *
+ * @param[out] perrno The error number, set if an error occured.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @param[out] buf This will hold the buffer of the datagram.
+ *
+ * @param[out] src The abstracted tsocket_address of the sender of the
+ * received datagram.
+ *
+ * @return The length of the datagram (0 is never returned!),
+ * -1 on error with perrno set to the actual errno.
+ *
+ * @see tdgram_recvfrom_send()
+ */
+ssize_t tdgram_recvfrom_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ uint8_t **buf,
+ struct tsocket_address **src);
+
+/**
+ * @brief Send a datagram to a destination endpoint.
+ *
+ * The function can be called to send a datagram (specified by a buf/len) to a
+ * destination endpoint (specified by dst). It's not allowed for len to be 0.
+ *
+ * It returns a 'tevent_req' handle, where the caller can register a callback
+ * with tevent_req_set_callback(). The callback is triggered when the specific
+ * implementation (assumes it) has delivered the datagram to the "wire".
+ *
+ * The callback is then supposed to get the result by calling
+ * tdgram_sendto_recv() on the 'tevent_req'.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] dgram The dgram context to work on.
+ *
+ * @param[in] buf The buffer to send.
+ *
+ * @param[in] len The length of the buffer to send. It has to be bigger
+ * than 0.
+ *
+ * @param[in] dst The destination to send the datagram to in form of a
+ * tsocket_address.
+ *
+ * @return Returns a 'tevent_req' handle, where the caller can
+ * register a callback with tevent_req_set_callback().
+ * NULL on fatal error.
+ *
+ * @see tdgram_inet_udp_socket()
+ * @see tdgram_unix_socket()
+ * @see tdgram_sendto_recv()
+ */
+struct tevent_req *tdgram_sendto_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tdgram_context *dgram,
+ const uint8_t *buf, size_t len,
+ const struct tsocket_address *dst);
+
+/**
+ * @brief Receive the result of the sent datagram.
+ *
+ * The caller can only have one outstanding tdgram_sendto_send() at a time
+ * otherwise the caller will get '*perrno = EBUSY'.
+ *
+ * @param[in] req The tevent request from tdgram_sendto_send().
+ *
+ * @param[out] perrno The error number, set if an error occured.
+ *
+ * @return The length of the datagram (0 is never returned!), -1 on
+ * error with perrno set to the actual errno.
+ *
+ * @see tdgram_sendto_send()
+ */
+ssize_t tdgram_sendto_recv(struct tevent_req *req,
+ int *perrno);
+
+/**
+ * @brief Shutdown/close an abstracted socket.
+ *
+ * It returns a 'tevent_req' handle, where the caller can register a callback
+ * with tevent_req_set_callback(). The callback is triggered when the specific
+ * implementation (assumes it) has delivered the datagram to the "wire".
+ *
+ * The callback is then supposed to get the result by calling
+ * tdgram_sendto_recv() on the 'tevent_req'.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] dgram The dgram context diconnect from.
+ *
+ * @return Returns a 'tevent_req' handle, where the caller can
+ * register a callback with tevent_req_set_callback().
+ * NULL on fatal error.
+ *
+ * @see tdgram_disconnect_recv()
+ */
+struct tevent_req *tdgram_disconnect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tdgram_context *dgram);
+
+/**
+ * @brief Receive the result from a tdgram_disconnect_send() request.
+ *
+ * The caller should make sure there're no outstanding tdgram_recvfrom_send()
+ * and tdgram_sendto_send() calls otherwise the caller will get
+ * '*perrno = EBUSY'.
+ *
+ * @param[in] req The tevent request from tdgram_disconnect_send().
+ *
+ * @param[out] perrno The error number, set if an error occured.
+ *
+ * @return The length of the datagram (0 is never returned!), -1 on
+ * error with perrno set to the actual errno.
+ *
+ * @see tdgram_disconnect_send()
+ */
+int tdgram_disconnect_recv(struct tevent_req *req,
+ int *perrno);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup tstream_context The tstream_context abstraction
+ * @ingroup tsocket
+ *
+ * The tstream_context is like an abstract class for stream based sockets. The
+ * interface provides async 'tevent_req' based functions on top functionality
+ * is similar to the readv(2)/writev(2)/close(2) syscalls.
+ *
+ * @note You can always use talloc_free(tstream) to cleanup the resources
+ * of the tstream_context on a fatal error.
+ *
+ * @{
+ */
+
+/**
+ * @brief Report the number of bytes received but not consumed yet.
+ *
+ * The tstream_pending_bytes() function reports how much bytes of the incoming
+ * stream have been received but not consumed yet.
+ *
+ * @param[in] stream The tstream_context to check for pending bytes.
+ *
+ * @return The number of bytes received, -1 on error with errno
+ * set.
+ */
+ssize_t tstream_pending_bytes(struct tstream_context *stream);
+
+/**
+ * @brief Read a specific amount of bytes from a stream socket.
+ *
+ * The function can be called to read for a specific amount of bytes from the
+ * stream into given buffers. The caller has to preallocate the buffers.
+ *
+ * The caller might need to use tstream_pending_bytes() if the protocol doesn't
+ * have a fixed pdu header containing the pdu size.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] stream The tstream context to work on.
+ *
+ * @param[out] vector A preallocated iovec to store the data to read.
+ *
+ * @param[in] count The number of buffers in the vector allocated.
+ *
+ * @return A 'tevent_req' handle, where the caller can register
+ * a callback with tevent_req_set_callback(). NULL on
+ * fatal error.
+ *
+ * @see tstream_unix_connect_send()
+ * @see tstream_inet_tcp_connect_send()
+ */
+struct tevent_req *tstream_readv_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ struct iovec *vector,
+ size_t count);
+
+/**
+ * @brief Get the result of a tstream_readv_send().
+ *
+ * The caller can only have one outstanding tstream_readv_send()
+ * at a time otherwise the caller will get *perrno = EBUSY.
+ *
+ * @param[in] req The tevent request from tstream_readv_send().
+ *
+ * @param[out] perrno The error number, set if an error occured.
+ *
+ * @return The length of the stream (0 is never returned!), -1 on
+ * error with perrno set to the actual errno.
+ */
+int tstream_readv_recv(struct tevent_req *req,
+ int *perrno);
+
+/**
+ * @brief Write buffers from a vector into a stream socket.
+ *
+ * The function can be called to write buffers from a given vector
+ * to a stream socket.
+ *
+ * You have to ensure that the vector is not empty.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] stream The tstream context to work on.
+ *
+ * @param[in] vector The iovec vector with data to write on a stream socket.
+ *
+ * @param[in] count The number of buffers in the vector to write.
+ *
+ * @return A 'tevent_req' handle, where the caller can register
+ * a callback with tevent_req_set_callback(). NULL on
+ * fatal error.
+ */
+struct tevent_req *tstream_writev_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ const struct iovec *vector,
+ size_t count);
+
+/**
+ * @brief Get the result of a tstream_writev_send().
+ *
+ * The caller can only have one outstanding tstream_writev_send()
+ * at a time otherwise the caller will get *perrno = EBUSY.
+ *
+ * @param[in] req The tevent request from tstream_writev_send().
+ *
+ * @param[out] perrno The error number, set if an error occured.
+ *
+ * @return The length of the stream (0 is never returned!), -1 on
+ * error with perrno set to the actual errno.
+ */
+int tstream_writev_recv(struct tevent_req *req,
+ int *perrno);
+
+/**
+ * @brief Shutdown/close an abstracted socket.
+ *
+ * It returns a 'tevent_req' handle, where the caller can register a callback
+ * with tevent_req_set_callback(). The callback is triggered when the specific
+ * implementation (assumes it) has delivered the stream to the "wire".
+ *
+ * The callback is then supposed to get the result by calling
+ * tdgram_sendto_recv() on the 'tevent_req'.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] stream The tstream context to work on.
+ *
+ * @return A 'tevent_req' handle, where the caller can register
+ * a callback with tevent_req_set_callback(). NULL on
+ * fatal error.
+ */
+struct tevent_req *tstream_disconnect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream);
+
+/**
+ * @brief Get the result of a tstream_disconnect_send().
+ *
+ * The caller can only have one outstanding tstream_writev_send()
+ * at a time otherwise the caller will get *perrno = EBUSY.
+ *
+ * @param[in] req The tevent request from tstream_disconnect_send().
+ *
+ * @param[out] perrno The error number, set if an error occured.
+ *
+ * @return The length of the stream (0 is never returned!), -1 on
+ * error with perrno set to the actual errno.
+ */
+int tstream_disconnect_recv(struct tevent_req *req,
+ int *perrno);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup tsocket_bsd tsocket_bsd - inet, inet6 and unix
+ * @ingroup tsocket
+ *
+ * The main tsocket library comes with implentations for BSD style ipv4, ipv6
+ * and unix sockets.
+ *
+ * @{
+ */
+
+#if DOXYGEN
+/**
+ * @brief Create a tsocket_address for ipv4 and ipv6 endpoint addresses.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] fam The family can be can be "ipv4", "ipv6" or "ip". With
+ * "ip" is autodetects "ipv4" or "ipv6" based on the
+ * addr.
+ *
+ * @param[in] addr A valid ip address string based on the selected family
+ * (dns names are not allowed!). It's valid to pass NULL,
+ * which gets mapped to "0.0.0.0" or "::".
+ *
+ * @param[in] port A valid port number.
+ *
+ * @param[out] _addr A tsocket_address pointer to store the information.
+ *
+ * @return 0 on success, -1 on error with errno set.
+ */
+int tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx,
+ const char *fam,
+ const char *addr,
+ uint16_t port,
+ struct tsocket_address **_addr);
+#else
+int _tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx,
+ const char *fam,
+ const char *addr,
+ uint16_t port,
+ struct tsocket_address **_addr,
+ const char *location);
+
+#define tsocket_address_inet_from_strings(mem_ctx, fam, addr, port, _addr) \
+ _tsocket_address_inet_from_strings(mem_ctx, fam, addr, port, _addr, \
+ __location__)
+#endif
+
+/**
+ * @brief Get the address of an 'inet' tsocket_address as a string.
+ *
+ * @param[in] addr The address to convert to a string.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @return A newly allocated string of the address, NULL on error
+ * with errno set.
+ */
+char *tsocket_address_inet_addr_string(const struct tsocket_address *addr,
+ TALLOC_CTX *mem_ctx);
+
+/**
+ * @brief Get the port number as an integer from an 'inet' tsocket_address.
+ *
+ * @param[in] addr The tsocket address to use.
+ *
+ * @return The port number, 0 on error with errno set.
+ */
+uint16_t tsocket_address_inet_port(const struct tsocket_address *addr);
+
+/**
+ * @brief Set the port number of an existing 'inet' tsocket_address.
+ *
+ * @param[in] addr The existing tsocket_address to use.
+ *
+ * @param[in] port The valid port number to set.
+ *
+ * @return 0 on success, -1 on error with errno set.
+ */
+int tsocket_address_inet_set_port(struct tsocket_address *addr,
+ uint16_t port);