[SCM] Samba Shared Repository - branch v3-5-test updated
Jeremy Allison
jra at samba.org
Tue Nov 3 13:28:46 MST 2009
The branch, v3-5-test has been updated
via bdd1622... tsocket: rewrite tsocket_guide.txt to reflect the current APIs
via 31f1d6f... tsocket_bsd: return -1 and set errno to ENAMETOOLONG if the unix path is too long
via 36801f0... tsocket: remove prototype of non-existing tsocket_address_inet_set_broadcast()
from 96f4bfc... Fix debug statements to use correct function name. Jeremy. (cherry picked from commit 31ce8eeb44d5060cfe85f42dc6ef092121b84a68)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test
- Log -----------------------------------------------------------------
commit bdd16229819f524078eb6cc3a8acf9c775985a20
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Nov 3 18:06:17 2009 +0100
tsocket: rewrite tsocket_guide.txt to reflect the current APIs
metze
(cherry picked from commit 97a32035bec03b76b67cb7088a7be1b7b3b9ac48)
commit 31f1d6f658827519c5dc51a4e32f95931d01d0b7
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Nov 3 17:23:07 2009 +0100
tsocket_bsd: return -1 and set errno to ENAMETOOLONG if the unix path is too long
metze
(cherry picked from commit eb39f6694055267302580bbf6afa988c82c55fed)
commit 36801f06f389c2e5ecd7d53db1e38e601fa48160
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Nov 3 17:22:27 2009 +0100
tsocket: remove prototype of non-existing tsocket_address_inet_set_broadcast()
metze
(cherry picked from commit 9b5d1e9e355d3d04f03744e025c6685ca8ad12cd)
-----------------------------------------------------------------------
Summary of changes:
lib/tsocket/tsocket.h | 2 -
lib/tsocket/tsocket_bsd.c | 7 +-
lib/tsocket/tsocket_guide.txt | 880 +++++++++++++++++++----------------------
3 files changed, 419 insertions(+), 470 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
index 8b0c80b..ae73113 100644
--- a/lib/tsocket/tsocket.h
+++ b/lib/tsocket/tsocket.h
@@ -117,8 +117,6 @@ char *tsocket_address_inet_addr_string(const struct tsocket_address *addr,
uint16_t tsocket_address_inet_port(const struct tsocket_address *addr);
int tsocket_address_inet_set_port(struct tsocket_address *addr,
uint16_t port);
-void tsocket_address_inet_set_broadcast(struct tsocket_address *addr,
- bool broadcast);
int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
const char *path,
diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c
index 8f1ccbe..05f5be1 100644
--- a/lib/tsocket/tsocket_bsd.c
+++ b/lib/tsocket/tsocket_bsd.c
@@ -444,9 +444,14 @@ int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
path = "";
}
+ if (strlen(path) > sizeof(un.sun_path)-1) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
ZERO_STRUCT(un);
un.sun_family = AF_UNIX;
- strncpy(un.sun_path, path, sizeof(un.sun_path));
+ strncpy(un.sun_path, path, sizeof(un.sun_path)-1);
ret = _tsocket_address_bsd_from_sockaddr(mem_ctx,
(struct sockaddr *)p,
diff --git a/lib/tsocket/tsocket_guide.txt b/lib/tsocket/tsocket_guide.txt
index a02fa37..ed903c6 100644
--- a/lib/tsocket/tsocket_guide.txt
+++ b/lib/tsocket/tsocket_guide.txt
@@ -2,32 +2,23 @@
Basic design of the tsocket abstraction
=======================================
-The tsocket layer is designed to match more or less
-the bsd socket layer, but it hides the filedescriptor
-within a opaque 'tsocket_context' structure to make virtual
-sockets possible. The virtual sockets can be encrypted tunnels
-(like TLS, SASL or GSSAPI) or named pipes over smb.
-
-The tsocket layer is a bit like an abstract class, which defines
-common methods to work with sockets in a non blocking fashion.
+The tsocket abstraction is splitted into two
+different kinds of communitation interfaces.
-The whole library is based on the talloc(3) and 'tevent' libraries.
+There's the "tstream_context" interface with abstracts
+the communication through a bidirectional
+byte stream between two endpoints.
-The 'tsocket_address' structure is the 2nd abstracted class
-which represends the address of a socket endpoint.
+And there's the "tdgram_context" interface
+with abstracts datagram based communication between any
+number of endpoints.
-Each different type of socket has its own constructor.
+Both interfaces share the "tsocket_address" abstraction
+for endpoint addresses.
-Typically the constructor for a tsocket_context is attached to
-the tsocket_address of the source endpoint. That means
-the tsocket_address_create_socket() function takes the
-tsocket_address of the local endpoint and creates a tsocket_context
-for the communication.
-
-For some usecases it's possible to wrap an existing socket into a
-tsocket_context, e.g. to wrap an existing pipe(2) into
-tsocket_context, so that you can use the same functions to
-communicate over the pipe.
+The whole library is based on the talloc(3) and 'tevent' libraries
+and provides "tevent_req" based "foo_send()"/"foo_recv()" functions pairs
+for all abstracted methods that need to be async.
The tsocket_address abstraction
===============================
@@ -51,453 +42,408 @@ via additional methods of the specific tsocket_address implementation.
struct tsocket_address *tsocket_address_copy(const struct tsocket_address *addr,
TALLOC_CTX *mem_ctx);
-There's a function to create a tsocket_context based on the given local
-socket endpoint. The return value is 0 on success and -1 on failure
-with errno holding the specific error. Specific details are descripted in later
-sections. Note not all specific implementation have to implement all socket
-types.
-
- enum tsocket_type {
- TSOCKET_TYPE_STREAM = 1,
- TSOCKET_TYPE_DGRAM,
- TSOCKET_TYPE_MESSAGE
- };
-
- int tsocket_address_create_socket(const struct tsocket_address *addr,
- enum tsocket_type type,
- TALLOC_CTX *mem_ctx,
- struct tsocket_context **sock);
-
-The tsocket_context abstraction
+The tdgram_context abstraction
+==============================
+
+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.
+
+The tdgram_recvfrom_send() method can be called to ask for the
+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.
+
+The callback is then supposed to get the result by calling
+tdgram_recvfrom_recv() on the 'tevent_req'. It returns -1
+and sets *perrno to the actual 'errno' on failure.
+Otherwise it returns the length of the datagram
+(0 is never returned!). *buf will contain the buffer of the
+datagram and *src the abstracted tsocket_address of the sender
+of the received datagram.
+
+The caller can only have one outstanding tdgram_recvfrom_send()
+at a time otherwise the caller will get *perrno = EBUSY.
+
+struct tevent_req *tdgram_recvfrom_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tdgram_context *dgram);
+ssize_t tdgram_recvfrom_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ uint8_t **buf,
+ struct tsocket_address **src);
+
+The tdgram_sendto_send() method 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 (thinks 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'. It returns -1
+and sets *perrno to the actual 'errno' on failure.
+Otherwise it returns the length of the datagram
+(0 is never returned!).
+
+The caller can only have one outstanding tdgram_sendto_send()
+at a time otherwise the caller will get *perrno = EBUSY.
+
+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);
+ssize_t tdgram_sendto_recv(struct tevent_req *req,
+ int *perrno);
+
+The tdgram_disconnect_send() method should be used to normally
+shutdown/close the abstracted socket.
+
+The caller should make sure there're no outstanding tdgram_recvfrom_send()
+and tdgram_sendto_send() calls otherwise the caller will get *perrno = EBUSY.
+
+Note: you can always use talloc_free(tdgram) to cleanup the resources
+of the tdgram_context on a fatal error.
+
+struct tevent_req *tdgram_disconnect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tdgram_context *dgram);
+int tdgram_disconnect_recv(struct tevent_req *req,
+ int *perrno);
+
+The tstream_context abstraction
===============================
-The tsocket_context is like an abstract class and represents
-a socket similar to bsd style sockets. The methods are more
-or less equal to the bsd socket api, while the filedescriptor
-is replaced by tsocket_context and sockaddr, socklen_t pairs
-are replaced by tsocket_address. The 'bind' operation happens
-in the specific constructor as the constructor is typically based
-on tsocket_address of local socket endpoint.
-
-All operations are by design non blocking and can return error
-values like EAGAIN, EINPROGRESS, EWOULDBLOCK or EINTR which
-indicate that the caller should retry the operation later.
-Also read the "The glue to tevent" section.
-
-The socket can of types:
- - TSOCKET_TYPE_STREAM is the equivalent to SOCK_STREAM in the bsd socket api.
- - TSOCKET_TYPE_DGRAM is the equivalent to SOCK_DGRAM in the bsd socket api.
- - TSOCKET_TYPE_MESSAGE operates on a connected socket and is therefore
- like TSOCKET_TYPE_STREAM, but the consumer needs to first read all
- data of a message, which was generated by one message 'write' on the sender,
- before the consumer gets data of the next message. This matches a bit
- like message mode pipes on windows. The concept is to transfer ordered
- messages between to endpoints.
-
-There's a function to connect to a remote endpoint. The behavior
-and error codes match the connect(2) function of the bsd socket api.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- int tsocket_connect(struct tsocket_context *sock,
- const struct tsocket_address *remote_addr);
-
-There's a function to listen for incoming connections. The behavior
-and error codes match the listen(2) function of the bsd socket api.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- int tsocket_listen(struct tsocket_context *sock,
- int queue_size);
-
-There's a function to accept incoming connections. The behavior
-and error codes match the accept(2) function of the bsd socket api.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- int tsocket_accept(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- struct tsocket_context **new_sock);
-
-There's a function to ask how many bytes are in input buffer
-of the connection. For sockets of type TSOCKET_TYPE_DGRAM or
-TSOCKET_TYPE_MESSAGE the size of the next available dgram/message
-is returned. A return value of -1 indicates a socket error
-and errno will hold the specific error code. If no data
-is available 0 is returned, but retry error codes like
-EINTR can also be returned.
-
- ssize_t tsocket_pending(struct tsocket_context *sock);
-
-There's a function to read data from the socket. The behavior
-and error codes match the readv(3) function, also take a look
-at the recv(2) function of the bsd socket api.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- int tsocket_readv(struct tsocket_context *sock,
- const struct iovec *vector, size_t count);
-
-There's a function to write data from the socket. The behavior
-and error codes match the writev(3) function, also take a look
-at the send(2) function of the bsd socket api.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- int tsocket_writev(struct tsocket_context *sock,
- const struct iovec *vector, size_t count);
-
-There's a function to read a datagram from a remote endpoint.
-The behavior and error codes match the recvfrom(2) function of
-the bsd socket api. As TSOCKET_TYPE_DGRAM sockets can also be
-used in connected mode src_addr can be NULL, if the caller don't
-want to get the source address. Maybe the specific tsocket_context
-implementation speficied some further details.
-
- ssize_t tsocket_recvfrom(struct tsocket_context *sock,
- uint8_t *data, size_t len,
- TALLOC_CTX *addr_ctx,
- struct tsocket_address **src_addr);
-
-There's a function to send a datagram to a remote endpoint the socket.
-The behavior and error codes match the recvfrom(2) function of the
-bsd socket api. As TSOCKET_TYPE_DGRAM sockets can also be used in
-connected mode dest_addr must be NULL in connected mode and a valid
-tsocket_address otherwise. Maybe the specific tsocket_context
-implementation speficied some further details.
-
- ssize_t tsocket_sendto(struct tsocket_context *sock,
- const uint8_t *data, size_t len,
- const struct tsocket_address *dest_addr);
-
-There's a function to get the current status of the socket.
-The behavior and error codes match the getsockopt(2) function
-of the bsd socket api, with SOL_SOCKET and SO_ERROR as arguments.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- int tsocket_get_status(const struct tsocket_context *sock);
-
-There's a function to get tsocket_address of the local endpoint.
-The behavior and error codes match the getsockname(2) function
-of the bsd socket api. Maybe the specific tsocket_context
-implementation speficied some further details.
-
- int tsocket_get_local_address(const struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- struct tsocket_address **local_addr);
-
-There's a function to get tsocket_address of the remote endpoint
-of a connected socket. The behavior and error codes match the
-getpeername(2) function of the bsd socket api. Maybe the specific
-tsocket_context implementation speficied some further details.
-
- int tsocket_get_remote_address(const struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- struct tsocket_address **remote_addr,
- const char *location);
-
-There's a function to ask for specific options of the socket.
-The behavior and error codes match the getsockopt(2) function
-of the bsd socket api. The option and value are represented as string
-values, where the 'value' parameter can be NULL is the caller don't want to
-get the value. The supported options and values are up to the specific
-tsocket_context implementation.
-
- int tsocket_get_option(const struct tsocket_context *sock,
- const char *option,
- TALLOC_CTX *mem_ctx,
- char **value);
-
-There's a function to set specific options of the socket.
-The behavior and error codes match the setsockopt(2) function
-of the bsd socket api. The option and value are represented as string
-values, where the 'value' parameter can be NULL. The supported options
-and values are up to the specific tsocket_context implementation.
-The 'force' parameter specifies whether an error should be returned
-for unsupported options.
-
- int tsocket_set_option(const struct tsocket_context *sock,
- const char *option,
- bool force,
- const char *value);
-
-There's a function to disconnect the socket. The behavior
-and error codes match the close(2) function of the bsd socket api.
-Maybe the specific tsocket_context implementation speficied some
-further details.
-
- void tsocket_disconnect(struct tsocket_context *sock);
-
-The glue to tevent
-==================
-
-As the tsocket library is based on the tevent library,
-there need to be functions to let the caller register
-callback functions, which are triggered when the socket
-is writeable or readable. Typically one would use
-tevent fd events, but in order to hide the filedescriptor
-the tsocket_context abstraction has their own functions.
-
-There's a function to set the currently active tevent_context
-for the socket. It's important there's only one tevent_context
-actively used with the socket. A second call will cancel
-all low level events made on the old tevent_context, it will
-also resets the send and recv handlers to NULL. If the caller
-sets attaches a new event context to the socket, the callback
-function also need to be registered again. It's important
-that the caller keeps the given tevent_context in memory
-and actively calls tsocket_set_event_context(sock, NULL)
-before calling talloc_free(event_context).
-The function returns 0 on success and -1 together with an errno
-on failure.
-
- int tsocket_set_event_context(struct tsocket_context *sock,
- struct tevent_context *ev);
-
-There's a function to register a callback function which is called
-when the socket is readable. If the caller don't want to get notified
-anymore the function should be called with NULL as handler.
-The function returns 0 on success and -1 together with an errno
-on failure.
-
- typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
- int tsocket_set_readable_handler(struct tsocket_context *sock,
- tsocket_event_handler_t handler,
- void *private_data);
-
-There's a function to register a callback function which is called
-when the socket is writeable. If the caller don't want to get notified
-anymore the function should be called with NULL as handler.
-The function returns 0 on success and -1 together with an errno
-on failure.
-
- typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
- int tsocket_set_writeable_handler(struct tsocket_context *sock,
- tsocket_event_handler_t handler,
- void *private_data);
-
-Note: if the socket is readable and writeable, only the writeable
- handler is called, this avoids deadlocks at the application level.
-
-Async helper functions
-======================
-
-To make the life easier for the callers, there're 'tevent_req' based
-helper functions for non-blocking io-operations. For each of this functions
-to work the caller must attach the tevent_context to the tsocket_context
-with tsocket_set_event_context(). Please remember that attching a new
-tevent_context will reset the event state of the socket and should only
-be done, when there's no async request is pending on the socket!
-
-The detailed calling conventions for 'tevent_req' based programming
-will be explained in the 'tevent' documentation.
-
-To receive the next availabe datagram from socket there's a wrapper
-for tsocket_recvfrom(). The caller virtually sends its desire to receive
-the next available datagram by calling the tsocket_recvfrom_send() function
-and attaches a callback function to the returned tevent_req via tevent_req_set_callback().
-The callback function is called when a datagram is available or an error has happened.
-The callback function needs to get the result by calling
-tsocket_recvfrom_recv(). The return value of tsocket_recvfrom_recv()
-matches the return value from tsocket_recvfrom(). A possible errno is delivered
-via the perrno parameter instead of the global errno variable. The datagram
-buffer and optional the source tsocket_address of the datagram are returned as talloc
-childs of the mem_ctx passed to tsocket_recvfrom_recv().
-It's important that the caller garanties that there's only one async
-read request on the socket at a time.
-
- struct tevent_req *tsocket_recvfrom_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx);
- ssize_t tsocket_recvfrom_recv(struct tevent_req *req,
- int *perrno,
- TALLOC_CTX *mem_ctx,
- uint8_t **buf,
- struct tsocket_address **src);
-
-To send a datagram there's a wrapper for tsocket_sendto().
-The caller calls tsocket_sendto_send() instead of tsocket_sendto()
-which returns a tevent_req allocated on the given TALLOC_CTX.
-The caller attaches a callback function to the returned tevent_req via
-tevent_req_set_callback(). The callback function is called when a datagram was
-deliviered into the socket or an error has happened.
-The callback function needs to get the result by calling
-tsocket_sendto_recv(). The return value of tsocket_sendto_recv()
-matches the return value from tsocket_sendto(). A possible errno is delivered
-via the perrno parameter instead of the global errno variable.
-Normal callers should not use this function directly, they should use
-tsocket_sendto_queue_send/recv() instead.
-
- struct tevent_req *tsocket_sendto_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const uint8_t *buf,
- size_t len,
- const struct tsocket_address *dst);
- ssize_t tsocket_sendto_recv(struct tevent_req *req, int *perrno);
-
-As only one async tsocket_sendto() call should happen at a time,
-there's a 'tevent_queue' is used to serialize the sendto requests.
-
- struct tevent_req *tsocket_sendto_queue_send(TALLOC_CTX *mem_ctx,
- struct tsocket_context *sock,
- struct tevent_queue *queue,
- const uint8_t *buf,
- size_t len,
- struct tsocket_address *dst);
- ssize_t tsocket_sendto_queue_recv(struct tevent_req *req, int *perrno);
-
-Ther's an async helper for tsocket_connect(), which should be used
-to connect TSOCKET_TYPE_STREAM based sockets.
-The caller virtually sends its desire to connect to the destination
-tsocket_address by calling tsocket_connect_send() and gets back a tevent_req.
-The caller sets a callback function via tevent_req_set_callback().
-The callback function is called if the tsocket is connected or an error has happened.
-The callback function needs to get the result by calling
-tsocket_connect_recv(). The return value of tsocket_connect_recv()
-matches the return value from tsocket_connect()/tsocket_get_status().
-A possible errno is delivered via the perrno parameter instead of the global
-errno variable.
-
- struct tevent_req *tsocket_connect_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const struct tsocket_address *dst);
- int tsocket_connect_recv(struct tevent_req *req, int *perrno);
-
-To send an 'iovec' there's a wrapper for tsocket_writev().
-The caller calls tsocket_writev_send() instead of tsocket_writev()
-which returns a tevent_req allocated on the given TALLOC_CTX.
-The caller attaches a callback function to the returned tevent_req via
-tevent_req_set_callback(). The callback function is called when the whole iovec
-was deliviered into the socket or an error has happened.
-The callback function needs to get the result by calling
-tsocket_writev_recv(). The return value of tsocket_writev_recv()
-matches the return value from tsocket_writev(). A possible errno is delivered
-via the perrno parameter instead of the global errno variable.
-Normal callers should not use this function directly, they should use
-tsocket_writev_queue_send/recv() instead.
-
- struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const struct iovec *vector,
- size_t count);
- int tsocket_writev_recv(struct tevent_req *req, int *perrno);
-
-As only one async tsocket_writev() call should happen at a time,
-there's a 'tevent_queue' is used to serialize the writev requests.
-
- struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
- struct tsocket_context *sock,
- struct tevent_queue *queue,
- const struct iovec *vector,
--
Samba Shared Repository
More information about the samba-cvs
mailing list