X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fsock.c;h=cac49e1db1648b93cc7cd55d933383dd274103f9;hb=5610952da2f4190573bc10467fcf249a9e7eff4b;hp=414c90775657294c0408ffb1e8c1eaea78ae8f0d;hpb=40bc8e8e47d2e171fd0fafe1eeecd2a0241cd33c;p=sysdb.git diff --git a/src/frontend/sock.c b/src/frontend/sock.c index 414c907..cac49e1 100644 --- a/src/frontend/sock.c +++ b/src/frontend/sock.c @@ -28,13 +28,14 @@ #include "sysdb.h" #include "core/error.h" #include "core/object.h" +#include "frontend/connection-private.h" #include "frontend/sock.h" #include "utils/channel.h" #include "utils/llist.h" +#include "utils/strbuf.h" #include - #include #include @@ -43,8 +44,6 @@ #include -#include - #include #include #include @@ -53,26 +52,10 @@ #include -/* name of connection objects */ -#define CONN_FD_PREFIX "conn#" -#define CONN_FD_PLACEHOLDER "XXXXXXX" - /* * private data types */ -typedef struct { - int fd; - struct sockaddr_storage client_addr; - socklen_t client_addr_len; -} connection_t; - -typedef struct { - sdb_object_t super; - connection_t conn; -} connection_obj_t; -#define CONN(obj) ((connection_obj_t *)(obj)) - typedef struct { char *address; int type; @@ -275,110 +258,10 @@ socket_close(sdb_fe_socket_t *sock) listener_close(sock->listeners + i); } /* socket_close */ -/* - * private data types - */ - -static int -connection_init(sdb_object_t *obj, va_list ap) -{ - connection_t *conn; - int sock_fd; - int sock_fl; - - assert(obj); - conn = &CONN(obj)->conn; - - sock_fd = va_arg(ap, int); - - conn->client_addr_len = sizeof(conn->client_addr); - conn->fd = accept(sock_fd, (struct sockaddr *)&conn->client_addr, - &conn->client_addr_len); - - if (conn->fd < 0) { - char buf[1024]; - sdb_log(SDB_LOG_ERR, "frontend: Failed to accept remote " - "connection: %s", sdb_strerror(errno, - buf, sizeof(buf))); - return -1; - } - - if (conn->client_addr.ss_family != AF_UNIX) { - sdb_log(SDB_LOG_ERR, "frontend: Accepted connection using " - "unexpected family type %d", conn->client_addr.ss_family); - return -1; - } - - sock_fl = fcntl(conn->fd, F_GETFL); - if (fcntl(conn->fd, F_SETFL, sock_fl | O_NONBLOCK)) { - char buf[1024]; - sdb_log(SDB_LOG_ERR, "frontend: Failed to switch connection conn#%i " - "to non-blocking mode: %s", conn->fd, - sdb_strerror(errno, buf, sizeof(buf))); - return -1; - } - - sdb_log(SDB_LOG_DEBUG, "frontend: Accepted connection on fd=%i", - conn->fd); - - /* update the object name */ - snprintf(obj->name + strlen(CONN_FD_PREFIX), - strlen(CONN_FD_PLACEHOLDER), "%i", conn->fd); - return 0; -} /* connection_init */ - -static void -connection_destroy(sdb_object_t *obj) -{ - connection_t *conn; - - assert(obj); - conn = &CONN(obj)->conn; - - sdb_log(SDB_LOG_DEBUG, "frontend: Closing connection on fd=%i", conn->fd); - close(conn->fd); - conn->fd = -1; -} /* connection_destroy */ - -static sdb_type_t connection_type = { - /* size = */ sizeof(connection_obj_t), - /* init = */ connection_init, - /* destroy = */ connection_destroy, -}; - /* * connection handler functions */ -/* returns negative value on error, 0 on EOF, number of packets else */ -static int -connection_read(int fd) -{ - int n = 0; - - while (42) { - int32_t cmd; - ssize_t status; - - errno = 0; - status = read(fd, &cmd, sizeof(cmd)); - if (status < 0) { - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) - return n + 1; - return (int)status; - } - else if (! status) /* EOF */ - return 0; - - /* XXX */ - sdb_log(SDB_LOG_DEBUG, "frontend: read command %i from fd=%i", - cmd, fd); - ++n; - } - - return n + 1; -} /* connection_read */ - static void * connection_handler(void *data) { @@ -388,7 +271,7 @@ connection_handler(void *data) while (42) { struct timespec timeout = { 0, 500000000 }; /* .5 seconds */ - connection_obj_t *conn; + sdb_conn_t *conn; int status; errno = 0; @@ -407,21 +290,22 @@ connection_handler(void *data) continue; } - status = connection_read(conn->conn.fd); + status = (int)sdb_connection_read(conn); if (status <= 0) { /* error or EOF -> close connection */ sdb_object_deref(SDB_OBJ(conn)); + continue; } - else { - if (sdb_llist_append(sock->open_connections, SDB_OBJ(conn))) { - sdb_log(SDB_LOG_ERR, "frontend: Failed to re-append " - "connection %s to list of open connections", - SDB_OBJ(conn)->name); - } - - /* pass ownership back to list; or destroy in case of an error */ - sdb_object_deref(SDB_OBJ(conn)); + + /* return the connection to the main loop */ + if (sdb_llist_append(sock->open_connections, SDB_OBJ(conn))) { + sdb_log(SDB_LOG_ERR, "frontend: Failed to re-append " + "connection %s to list of open connections", + SDB_OBJ(conn)->name); } + + /* pass ownership back to list; or destroy in case of an error */ + sdb_object_deref(SDB_OBJ(conn)); } return NULL; } /* connection_handler */ @@ -430,25 +314,21 @@ static int connection_accept(sdb_fe_socket_t *sock, listener_t *listener) { sdb_object_t *obj; + int status; - /* the placeholder will be replaced with the accepted file - * descriptor when initializing the object */ - obj = sdb_object_create(CONN_FD_PREFIX CONN_FD_PLACEHOLDER, - connection_type, listener->sock_fd); + obj = SDB_OBJ(sdb_connection_accept(listener->sock_fd)); if (! obj) return -1; - if (sdb_llist_append(sock->open_connections, obj)) { + status = sdb_llist_append(sock->open_connections, obj); + if (status) sdb_log(SDB_LOG_ERR, "frontend: Failed to append " "connection %s to list of open connections", obj->name); - sdb_object_deref(obj); - return -1; - } - /* hand ownership over to the list */ + /* hand ownership over to the list; or destroy in case of an error */ sdb_object_deref(obj); - return 0; + return status; } /* connection_accept */ static int @@ -475,11 +355,11 @@ socket_handle_incoming(sdb_fe_socket_t *sock, while (sdb_llist_iter_has_next(iter)) { sdb_object_t *obj = sdb_llist_iter_get_next(iter); - if (FD_ISSET(CONN(obj)->conn.fd, exceptions)) + if (FD_ISSET(CONN(obj)->fd, exceptions)) sdb_log(SDB_LOG_INFO, "Exception on fd %d", - CONN(obj)->conn.fd); + CONN(obj)->fd); - if (FD_ISSET(CONN(obj)->conn.fd, ready)) { + if (FD_ISSET(CONN(obj)->fd, ready)) { sdb_llist_iter_remove_current(iter); sdb_channel_write(sock->chan, &obj); } @@ -570,7 +450,7 @@ sdb_fe_sock_listen_and_serve(sdb_fe_socket_t *sock, sdb_fe_loop_t *loop) max_listen_fd = listener->sock_fd; } - sock->chan = sdb_channel_create(1024, sizeof(connection_obj_t *)); + sock->chan = sdb_channel_create(1024, sizeof(sdb_conn_t *)); if (! sock->chan) { socket_close(sock); return -1; @@ -605,11 +485,11 @@ sdb_fe_sock_listen_and_serve(sdb_fe_socket_t *sock, sdb_fe_loop_t *loop) while (sdb_llist_iter_has_next(iter)) { sdb_object_t *obj = sdb_llist_iter_get_next(iter); - FD_SET(CONN(obj)->conn.fd, &ready); - FD_SET(CONN(obj)->conn.fd, &exceptions); + FD_SET(CONN(obj)->fd, &ready); + FD_SET(CONN(obj)->fd, &exceptions); - if (CONN(obj)->conn.fd > max_fd) - max_fd = CONN(obj)->conn.fd; + if (CONN(obj)->fd > max_fd) + max_fd = CONN(obj)->fd; } sdb_llist_iter_destroy(iter);