+ struct tstream_context **stream);
+#else
+int _tstream_unix_connect_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ struct tstream_context **stream,
+ const char *location);
+#define tstream_unix_connect_recv(req, perrno, mem_ctx, stream) \
+ _tstream_unix_connect_recv(req, perrno, mem_ctx, stream, \
+ __location__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Create two connected 'unix' tsocket_contexts for stream based
+ * communication.
+ *
+ * @param[in] mem_ctx1 The talloc memory context to use for stream1.
+ *
+ * @param[in] stream1 The first stream to connect.
+ *
+ * @param[in] mem_ctx2 The talloc memory context to use for stream2.
+ *
+ * @param[in] stream2 The second stream to connect.
+ *
+ * @return 0 on success, -1 on error with errno set.
+ */
+int tstream_unix_socketpair(TALLOC_CTX *mem_ctx1,
+ struct tstream_context **stream1,
+ TALLOC_CTX *mem_ctx2,
+ struct tstream_context **stream2);
+#else
+int _tstream_unix_socketpair(TALLOC_CTX *mem_ctx1,
+ struct tstream_context **_stream1,
+ TALLOC_CTX *mem_ctx2,
+ struct tstream_context **_stream2,
+ const char *location);
+
+#define tstream_unix_socketpair(mem_ctx1, stream1, mem_ctx2, stream2) \
+ _tstream_unix_socketpair(mem_ctx1, stream1, mem_ctx2, stream2, \
+ __location__)
+#endif
+
+struct sockaddr;
+
+#ifdef DOXYGEN
+/**
+ * @brief Convert a tsocket address to a bsd socket address.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] sa The sockaddr structure to convert.
+ *
+ * @param[in] sa_socklen The lenth of the sockaddr sturucte.
+ *
+ * @param[out] addr The tsocket pointer to allocate and fill.
+ *
+ * @return 0 on success, -1 on error with errno set.
+ */
+int tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
+ 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,
+ size_t sa_socklen,
+ struct tsocket_address **_addr,
+ const char *location);
+
+#define tsocket_address_bsd_from_sockaddr(mem_ctx, sa, sa_socklen, _addr) \
+ _tsocket_address_bsd_from_sockaddr(mem_ctx, sa, sa_socklen, _addr, \
+ __location__)
+#endif
+
+/**
+ * @brief Fill a bsd sockaddr structure.
+ *
+ * @param[in] addr The tsocket address structure to use.
+ *
+ * @param[in] sa The bsd sockaddr structure to fill out.
+ *
+ * @param[in] sa_socklen The length of the bsd sockaddr structure to fill out.
+ *
+ * @return The actual size of the sockaddr structure, -1 on error
+ * with errno set. The size could differ from sa_socklen.
+ *
+ * @code
+ * ssize_t socklen;
+ * struct sockaddr_storage ss;
+ *
+ * socklen = tsocket_address_bsd_sockaddr(taddr,
+ * (struct sockaddr *) &ss,
+ * sizeof(struct sockaddr_storage));
+ * if (socklen < 0) {
+ * return -1;
+ * }
+ * @endcode
+ */
+ssize_t tsocket_address_bsd_sockaddr(const struct tsocket_address *addr,
+ struct sockaddr *sa,
+ size_t sa_socklen);
+
+#ifdef DOXYGEN
+/**
+ * @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.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] fd The non blocking fd to use!
+ *
+ * @param[in] stream The filed tstream_context you allocated before.
+ *
+ * @return 0 on success, -1 on error with errno set.
+ *
+ * @warning You should read the tsocket_bsd.c code and unterstand it in order
+ * use this function.
+ */
+int tstream_bsd_existing_socket(TALLOC_CTX *mem_ctx,
+ int fd,
+ struct tstream_context **stream);
+#else
+int _tstream_bsd_existing_socket(TALLOC_CTX *mem_ctx,
+ int fd,
+ struct tstream_context **_stream,
+ const char *location);
+#define tstream_bsd_existing_socket(mem_ctx, fd, stream) \
+ _tstream_bsd_existing_socket(mem_ctx, fd, stream, \
+ __location__)
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup tsocket_helper Queue and PDU helpers
+ * @ingroup tsocket
+ *
+ * In order to make the live easier for callers which want to implement a
+ * function to receive a full PDU with a single async function pair, there're
+ * some helper functions.
+ *
+ * There're some cases where the caller wants doesn't care about the order of
+ * doing IO on the abstracted sockets.
+ *
+ * @{
+ */
+
+/**
+ * @brief Queue a dgram blob 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.
+ *
+ * The caller needs to make sure that all non-scalar input parameters hang
+ * arround for the whole lifetime of the request.
+ *
+ * @param[in] mem_ctx The memory context for the result.
+ *
+ * @param[in] ev The event context the operation should work on.
+ *
+ * @param[in] dgram The tdgram_context to send the message buffer.
+ *
+ * @param[in] queue The existing dgram queue.
+ *
+ * @param[in] buf The message buffer to send.
+ *
+ * @param[in] len The message length.
+ *
+ * @param[in] dst The destination socket address.
+ *
+ * @return The async request handle. NULL on fatal error.
+ *
+ * @see tdgram_sendto_queue_recv()
+ */
+struct tevent_req *tdgram_sendto_queue_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tdgram_context *dgram,
+ struct tevent_queue *queue,
+ const uint8_t *buf,
+ size_t len,
+ struct tsocket_address *dst);
+
+/**
+ * @brief Receive the result of the sent dgram blob.
+ *
+ * @param[in] req The tevent request from tdgram_sendto_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.
+ */
+ssize_t tdgram_sendto_queue_recv(struct tevent_req *req, int *perrno);
+
+typedef int (*tstream_readv_pdu_next_vector_t)(struct tstream_context *stream,
+ void *private_data,
+ TALLOC_CTX *mem_ctx,
+ struct iovec **vector,
+ size_t *count);
+
+struct tevent_req *tstream_readv_pdu_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ tstream_readv_pdu_next_vector_t next_vector_fn,
+ void *next_vector_private);
+int tstream_readv_pdu_recv(struct tevent_req *req, int *perrno);
+
+/**
+ * @brief Queue a read request for a PDU on the 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.
+ *
+ * @param[in] mem_ctx The memory context for the result
+ *
+ * @param[in] ev The tevent_context to run on
+ *
+ * @param[in] stream The stream to send data through
+ *
+ * @param[in] queue The existing send queue
+ *
+ * @param[in] next_vector_fn The next vector function
+ *
+ * @param[in] next_vector_private The private_data of the next vector function
+ *
+ * @return The async request handle. NULL on fatal error.
+ *
+ * @see tstream_readv_pdu_queue_recv()
+ */
+struct tevent_req *tstream_readv_pdu_queue_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ struct tevent_queue *queue,
+ tstream_readv_pdu_next_vector_t next_vector_fn,
+ void *next_vector_private);
+
+/**
+ * @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 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
+ *
+ * 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.
+ *
+ * The caller needs to make sure that all non-scalar input parameters hang
+ * arround for the whole lifetime of the request.
+ *
+ * @param[in] mem_ctx The memory context for the result.
+ *
+ * @param[in] ev The tevent_context to run on.
+ *
+ * @param[in] stream The stream to send data through.
+ *
+ * @param[in] queue The existing send queue.
+ *
+ * @param[in] vector The iovec vector so write.
+ *
+ * @param[in] count The size of the vector.
+ *
+ * @return The async request handle. NULL on fatal error.
+ */
+struct tevent_req *tstream_writev_queue_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ struct tevent_queue *queue,
+ const struct iovec *vector,
+ size_t count);
+
+/**
+ * @brief Receive the result of the sent dgram blob.
+ *
+ * @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
+ * error with perrno set to the actual errno.
+ */
+int tstream_writev_queue_recv(struct tevent_req *req, int *perrno);
+
+/**
+ * @}
+ */