src/lib/tcp_internal.h
branchnew-lib-errors
changeset 219 cefec18b8268
parent 177 a74b55104fb9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/tcp_internal.h	Thu May 28 01:17:36 2009 +0300
@@ -0,0 +1,170 @@
+#ifndef LIBQMSK_TCP_INTERNAL_H
+#define LIBQMSK_TCP_INTERNAL_H
+
+/**
+ * @file
+ *
+ * Internal TCP interface for implementations
+ */
+#include "tcp.h"
+#include "resolve.h"
+#include "transport_fd.h"
+#include "transport_internal.h"
+#include "service_internal.h"
+#include "error.h"
+
+#include <event2/event.h>
+#include <event2/util.h>
+
+/**
+ * Create a new socket() using the given addr's family/socktype/protocol and return it.
+ *
+ * In case of errors, this returns -err_t
+ *
+ * @param addr the addrinfo to create the socket for
+ * @param err returned error info
+ * @return new fd on success, -err_t on error
+ */
+int tcp_sock_create (const struct addrinfo *addr, error_t *err);
+
+/**
+ * Return the socket's current error code via err->extra.
+ *
+ * In case getting the socket error code itself fails, this will return normal error code/info.
+ *
+ * Otherwise, this will return SUCCESS, with the errno value stored in err->extra.
+ */
+err_t tcp_sock_error (evutil_socket_t sock, error_t *err);
+
+
+/**
+ * TCP transport type
+ */
+extern const struct transport_type tcp_transport_type;
+
+/**
+ * Base TCP transport 
+ *
+ * XXX: currently just the same as transport_fd, but this will probably change
+ */
+struct tcp_transport {
+    /** Base FD-based implementation */
+    struct transport_fd base_fd;
+};
+
+/**
+ * Initialize the tcp_transport state.
+ *
+ * This initializes the transport_fd base using the global sock_ctx::ev_base and the given socket.
+ */
+void tcp_transport_init (struct tcp_transport *trans, evutil_socket_t sock);
+
+/**
+ * Create a new tcp_transport with the given sock.
+ *
+ * For convenience, this will also make the sock nonblocking.
+ *
+ * In case of errors, this will the socket.
+ *
+ * @param trans_ptr returned tcp_transport
+ * @param info the transport user settings
+ * @param sock the unused TCP socket
+ * @param err returned error info
+ */
+err_t tcp_transport_create (struct tcp_transport **trans_ptr, const struct transport_info *info, evutil_socket_t sock, error_t *err);
+
+/**
+ * The transport as now connected, this sets up the intitial user settings, and invokes the callback.
+ *
+ * XXX: this does an 'indirect' call to transport_connected().
+ *
+ * @param err returned error info
+ */
+err_t tcp_transport_connected (struct tcp_transport *trans, error_t *err);
+
+/**
+ * Deinitialize the transport state, terminating the connection and releasing resources.
+ */
+void tcp_transport_deinit (struct tcp_transport *trans);
+
+/**
+ * Deinitialize and free the given tcp_transport
+ */
+void tcp_transport_destroy (struct tcp_transport *trans);
+
+/**
+ * TCP client transport type
+ */
+extern const struct transport_type tcp_client_type;
+
+/**
+ * TCP client state
+ */
+struct tcp_client {
+    /** Base transport stuff */
+    struct tcp_transport base_trans;
+
+    /** The resolver lookup result for the async connect process */
+    struct resolve_result rr;
+};
+
+/**
+ * Initialize the tcp_client state
+ */
+void tcp_client_init (struct tcp_client *client);
+
+/**
+ * Attempt to connect asyncronously to the given hostname/service. Once a connection has been established, this will
+ * call transport_connected(), so you can register transport_methods::_connected if layering on top of TCP.
+ *
+ * In case of errors while starting the async connect process, an error code will be returned. If the connect fails
+ * later on, transport_connected() will be called with the error code.
+ *
+ * The sock must have been initialized using sock_tcp_init().
+ *
+ * @param client the unconnected TCP client socket to connect with
+ * @param hostname the hostname to resolve
+ * @param service the service to connect to
+ * @param err returned error info for immediate errors
+ */
+err_t tcp_client_connect_async (struct tcp_client *client, const char *hostname, const char *service, error_t *err);
+
+/**
+ * Deinitialize the tcp_client's state, including the tcp_transport state.
+ */
+void tcp_client_deinit (struct tcp_client *client);
+
+
+
+/**
+ * TCP service type
+ */
+extern const struct service_type tcp_server_type;
+
+/**
+ * TCP service state
+ */
+struct tcp_server {
+    /** Base service state */
+    struct service base_service;
+    
+    /** The input event with our listen() socket */
+    struct event *ev;
+};
+
+/**
+ * The listen() backlog
+ */
+#define TCP_SERVER_BACKLOG 5
+
+/**
+ * Open the listening socket on the given interface/service.
+ */
+err_t tcp_server_listen (struct tcp_server *serv, const char *interface, const char *service, error_t *err);
+
+/**
+ * Release the tcp_server's state, and cleanup the struct.
+ */
+void tcp_server_deinit (struct tcp_server *serv);
+
+#endif /* TCP_INTERNAL_H */