From 9544985ccbb20d7f8377c63a4e59d1ff97b844ac Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Mon, 3 Feb 2014 10:05:00 -0800 Subject: Convert fd to Session* where meaningful --- src/common/socket.cpp | 197 +++++++++++++++++++++++++------------------------- src/common/socket.hpp | 120 ++++++++++++++++-------------- 2 files changed, 164 insertions(+), 153 deletions(-) (limited to 'src/common') diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 61552c7..1c5bcbc 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -29,98 +29,98 @@ const uint32_t WFIFO_SIZE = 65536; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" -std::array, FD_SETSIZE> session; +std::array, FD_SETSIZE> session; #pragma GCC diagnostic pop /// clean up by discarding handled bytes inline -void RFIFOFLUSH(int fd) +void RFIFOFLUSH(Session *s) { - really_memmove(&session[fd]->rdata[0], &session[fd]->rdata[session[fd]->rdata_pos], RFIFOREST(fd)); - session[fd]->rdata_size = RFIFOREST(fd); - session[fd]->rdata_pos = 0; + really_memmove(&s->rdata[0], &s->rdata[s->rdata_pos], RFIFOREST(s)); + s->rdata_size = RFIFOREST(s); + s->rdata_pos = 0; } /// how much room there is to read more data inline -size_t RFIFOSPACE(int fd) +size_t RFIFOSPACE(Session *s) { - return session[fd]->max_rdata - session[fd]->rdata_size; + return s->max_rdata - s->rdata_size; } /// Discard all input static -void null_parse(int fd); +void null_parse(Session *s); /// Default parser for new connections static -void (*default_func_parse)(int) = null_parse; +void (*default_func_parse)(Session *) = null_parse; -void set_defaultparse(void (*defaultparse)(int)) +void set_defaultparse(void (*defaultparse)(Session *)) { default_func_parse = defaultparse; } /// Read from socket to the queue static -void recv_to_fifo(int fd) +void recv_to_fifo(Session *s) { - if (session[fd]->eof) + if (s->eof) return; - ssize_t len = read(fd, &session[fd]->rdata[session[fd]->rdata_size], - RFIFOSPACE(fd)); + ssize_t len = read(s->fd, &s->rdata[s->rdata_size], + RFIFOSPACE(s)); if (len > 0) { - session[fd]->rdata_size += len; - session[fd]->connected = 1; + s->rdata_size += len; + s->connected = 1; } else { - session[fd]->eof = 1; + s->eof = 1; } } static -void send_from_fifo(int fd) +void send_from_fifo(Session *s) { - if (session[fd]->eof) + if (s->eof) return; - ssize_t len = write(fd, &session[fd]->wdata[0], session[fd]->wdata_size); + ssize_t len = write(s->fd, &s->wdata[0], s->wdata_size); if (len > 0) { - session[fd]->wdata_size -= len; - if (session[fd]->wdata_size) + s->wdata_size -= len; + if (s->wdata_size) { - really_memmove(&session[fd]->wdata[0], &session[fd]->wdata[len], - session[fd]->wdata_size); + really_memmove(&s->wdata[0], &s->wdata[len], + s->wdata_size); } - session[fd]->connected = 1; + s->connected = 1; } else { - session[fd]->eof = 1; + s->eof = 1; } } static -void null_parse(int fd) +void null_parse(Session *s) { - PRINTF("null_parse : %d\n", fd); - RFIFOSKIP(fd, RFIFOREST(fd)); + PRINTF("null_parse : %d\n", s); + RFIFOSKIP(s, RFIFOREST(s)); } static -void connect_client(int listen_fd) +void connect_client(Session *ls) { struct sockaddr_in client_address; socklen_t len = sizeof(client_address); - int fd = accept(listen_fd, reinterpret_cast(&client_address), &len); + int fd = accept(ls->fd, reinterpret_cast(&client_address), &len); if (fd == -1) { perror("accept"); @@ -165,28 +165,30 @@ void connect_client(int listen_fd) fcntl(fd, F_SETFL, O_NONBLOCK); - session[fd] = make_unique(); - session[fd]->rdata.new_(RFIFO_SIZE); - session[fd]->wdata.new_(WFIFO_SIZE); - - session[fd]->max_rdata = RFIFO_SIZE; - session[fd]->max_wdata = WFIFO_SIZE; - session[fd]->func_recv = recv_to_fifo; - session[fd]->func_send = send_from_fifo; - session[fd]->func_parse = default_func_parse; - session[fd]->client_ip = IP4Address(client_address.sin_addr); - session[fd]->created = TimeT::now(); - session[fd]->connected = 0; + session[fd] = make_unique(); + Session *s = session[fd].get(); + s->fd = fd; + s->rdata.new_(RFIFO_SIZE); + s->wdata.new_(WFIFO_SIZE); + + s->max_rdata = RFIFO_SIZE; + s->max_wdata = WFIFO_SIZE; + s->func_recv = recv_to_fifo; + s->func_send = send_from_fifo; + s->func_parse = default_func_parse; + s->client_ip = IP4Address(client_address.sin_addr); + s->created = TimeT::now(); + s->connected = 0; } -int make_listen_port(uint16_t port) +Session *make_listen_port(uint16_t port) { struct sockaddr_in server_address; int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("socket"); - return -1; + return nullptr; } if (fd_max <= fd) fd_max = fd + 1; @@ -231,23 +233,25 @@ int make_listen_port(uint16_t port) FD_SET(fd, &readfds); #pragma GCC diagnostic pop - session[fd] = make_unique(); + session[fd] = make_unique(); + Session *s = session[fd].get(); + s->fd = fd; - session[fd]->func_recv = connect_client; - session[fd]->created = TimeT::now(); - session[fd]->connected = 1; + s->func_recv = connect_client; + s->created = TimeT::now(); + s->connected = 1; - return fd; + return s; } -int make_connection(IP4Address ip, uint16_t port) +Session *make_connection(IP4Address ip, uint16_t port) { struct sockaddr_in server_address; int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("socket"); - return -1; + return nullptr; } if (fd_max <= fd) fd_max = fd + 1; @@ -285,28 +289,29 @@ int make_connection(IP4Address ip, uint16_t port) FD_SET(fd, &readfds); #pragma GCC diagnostic pop - session[fd] = make_unique(); - session[fd]->rdata.new_(RFIFO_SIZE); - session[fd]->wdata.new_(WFIFO_SIZE); - - session[fd]->max_rdata = RFIFO_SIZE; - session[fd]->max_wdata = WFIFO_SIZE; - session[fd]->func_recv = recv_to_fifo; - session[fd]->func_send = send_from_fifo; - session[fd]->func_parse = default_func_parse; - session[fd]->created = TimeT::now(); - session[fd]->connected = 1; - - return fd; + session[fd] = make_unique(); + Session *s = session[fd].get(); + s->fd = fd; + s->rdata.new_(RFIFO_SIZE); + s->wdata.new_(WFIFO_SIZE); + + s->max_rdata = RFIFO_SIZE; + s->max_wdata = WFIFO_SIZE; + s->func_recv = recv_to_fifo; + s->func_send = send_from_fifo; + s->func_parse = default_func_parse; + s->created = TimeT::now(); + s->connected = 1; + + return s; } -void delete_session(int fd) +void delete_session(Session *s) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" - if (fd < 0 || fd >= FD_SETSIZE) -#pragma GCC diagnostic pop + if (!s) return; + + int fd = s->fd; // If this was the highest fd, decrease it // We could add a loop to decrement fd_max further for every null session, // but this is cheap and good enough for the typical case @@ -316,11 +321,10 @@ void delete_session(int fd) #pragma GCC diagnostic ignored "-Wold-style-cast" FD_CLR(fd, &readfds); #pragma GCC diagnostic pop - if (session[fd]) { - session[fd]->rdata.delete_(); - session[fd]->wdata.delete_(); - session[fd]->session_data.reset(); + s->rdata.delete_(); + s->wdata.delete_(); + s->session_data.reset(); session[fd].reset(); } @@ -329,9 +333,8 @@ void delete_session(int fd) close(fd); } -void realloc_fifo(int fd, size_t rfifo_size, size_t wfifo_size) +void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size) { - const std::unique_ptr& s = session[fd]; if (s->max_rdata != rfifo_size && s->rdata_size < rfifo_size) { s->rdata.resize(rfifo_size); @@ -344,18 +347,17 @@ void realloc_fifo(int fd, size_t rfifo_size, size_t wfifo_size) } } -void WFIFOSET(int fd, size_t len) +void WFIFOSET(Session *s, size_t len) { - std::unique_ptr& s = session[fd]; if (s->wdata_size + len + 16384 > s->max_wdata) { - realloc_fifo(fd, s->max_rdata, s->max_wdata << 1); - PRINTF("socket: %d wdata expanded to %zu bytes.\n", fd, s->max_wdata); + realloc_fifo(s, s->max_rdata, s->max_wdata << 1); + PRINTF("socket: %d wdata expanded to %zu bytes.\n", s, s->max_wdata); } if (s->wdata_size + len + 2048 < s->max_wdata) s->wdata_size += len; else - FPRINTF(stderr, "socket: %d wdata lost !!\n", fd), abort(); + FPRINTF(stderr, "socket: %d wdata lost !!\n", s), abort(); } void do_sendrecv(interval_t next_ms) @@ -384,26 +386,27 @@ void do_sendrecv(interval_t next_ms) return; for (int i = 0; i < fd_max; i++) { - if (!session[i]) + Session *s = session[i].get(); + if (!s) continue; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" if (FD_ISSET(i, &wfd)) #pragma GCC diagnostic pop { - if (session[i]->func_send) + if (s->func_send) //send_from_fifo(i); - session[i]->func_send(i); + s->func_send(s); } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" if (FD_ISSET(i, &rfd)) #pragma GCC diagnostic pop { - if (session[i]->func_recv) + if (s->func_recv) //recv_to_fifo(i); //or connect_client(i); - session[i]->func_recv(i); + s->func_recv(s); } } } @@ -412,25 +415,26 @@ void do_parsepacket(void) { for (int i = 0; i < fd_max; i++) { - if (!session[i]) + Session *s = session[i].get(); + if (!s) continue; - if (!session[i]->connected - && static_cast(TimeT::now()) - static_cast(session[i]->created) > CONNECT_TIMEOUT) + if (!s->connected + && static_cast(TimeT::now()) - static_cast(s->created) > CONNECT_TIMEOUT) { PRINTF("Session #%d timed out\n", i); - session[i]->eof = 1; + s->eof = 1; } - if (!session[i]->rdata_size && !session[i]->eof) + if (!s->rdata_size && !s->eof) continue; - if (session[i]->func_parse) + if (s->func_parse) { - session[i]->func_parse(i); + s->func_parse(s); /// some func_parse may call delete_session - if (!session[i]) + if (!s) continue; } /// Reclaim buffer space for what was read - RFIFOFLUSH(i); + RFIFOFLUSH(s); } } @@ -442,9 +446,8 @@ void do_socket(void) #pragma GCC diagnostic pop } -void RFIFOSKIP(int fd, size_t len) +void RFIFOSKIP(Session *s, size_t len) { - std::unique_ptr& s = session[fd]; s->rdata_pos += len; if (s->rdata_size < s->rdata_pos) diff --git a/src/common/socket.hpp b/src/common/socket.hpp index 8a2ee3a..4d51604 100644 --- a/src/common/socket.hpp +++ b/src/common/socket.hpp @@ -29,7 +29,7 @@ struct SessionDeleter // Struct declaration -struct socket_data +struct Session { /// Checks whether a newly-connected socket actually does anything TimeT created; @@ -54,17 +54,25 @@ struct socket_data /// Only called when select() indicates the socket is ready /// If, after that, nothing is read, it sets eof // These could probably be hard-coded with a little work - void (*func_recv)(int); - void (*func_send)(int); + void (*func_recv)(Session *); + void (*func_send)(Session *); /// This is the important one /// Set to different functions depending on whether the connection /// is a player or a server/ladmin /// Can be set explicitly or via set_defaultparse - void (*func_parse)(int); + void (*func_parse)(Session *); /// Server-specific data type std::unique_ptr session_data; + + int fd; }; +inline +int convert_for_printf(Session *s) +{ + return s->fd; +} + // save file descriptors for important stuff constexpr int SOFT_LIMIT = FD_SETSIZE - 50; @@ -73,21 +81,21 @@ constexpr int CONNECT_TIMEOUT = 15; /// Everyone who has connected // note: call delete_session(i) to null out an element -extern std::array, FD_SETSIZE> session; +extern std::array, FD_SETSIZE> session; /// Maximum used FD, +1 extern int fd_max; /// open a socket, bind, and listen. Return an fd, or -1 if socket() fails, /// but exit if bind() or listen() fails -int make_listen_port(uint16_t port); +Session *make_listen_port(uint16_t port); /// Connect to an address, return a connected socket or -1 // FIXME - this is IPv4 only! -int make_connection(IP4Address ip, uint16_t port); +Session *make_connection(IP4Address ip, uint16_t port); /// free() the structure and close() the fd -void delete_session(int); +void delete_session(Session *); /// Make a the internal queues bigger -void realloc_fifo(int fd, size_t rfifo_size, size_t wfifo_size); +void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size); /// Update all sockets that can be read/written from the queues void do_sendrecv(interval_t next); /// Call the parser function for every socket that has read data @@ -99,7 +107,7 @@ void do_socket(void); /// Change the default parser for newly connected clients // typically called once per server, but individual clients may identify // themselves as servers -void set_defaultparse(void(*defaultparse)(int)); +void set_defaultparse(void(*defaultparse)(Session *)); template uint8_t *pod_addressof_m(T& structure) @@ -118,68 +126,68 @@ const uint8_t *pod_addressof_c(const T& structure) /// Check how much can be read inline -size_t RFIFOREST(int fd) +size_t RFIFOREST(Session *s) { - return session[fd]->rdata_size - session[fd]->rdata_pos; + return s->rdata_size - s->rdata_pos; } /// Read from the queue inline -const void *RFIFOP(int fd, size_t pos) +const void *RFIFOP(Session *s, size_t pos) { - return &session[fd]->rdata[session[fd]->rdata_pos + pos]; + return &s->rdata[s->rdata_pos + pos]; } inline -uint8_t RFIFOB(int fd, size_t pos) +uint8_t RFIFOB(Session *s, size_t pos) { - return *static_cast(RFIFOP(fd, pos)); + return *static_cast(RFIFOP(s, pos)); } inline -uint16_t RFIFOW(int fd, size_t pos) +uint16_t RFIFOW(Session *s, size_t pos) { - return *static_cast(RFIFOP(fd, pos)); + return *static_cast(RFIFOP(s, pos)); } inline -uint32_t RFIFOL(int fd, size_t pos) +uint32_t RFIFOL(Session *s, size_t pos) { - return *static_cast(RFIFOP(fd, pos)); + return *static_cast(RFIFOP(s, pos)); } template -void RFIFO_STRUCT(int fd, size_t pos, T& structure) +void RFIFO_STRUCT(Session *s, size_t pos, T& structure) { - really_memcpy(pod_addressof_m(structure), static_cast(RFIFOP(fd, pos)), sizeof(T)); + really_memcpy(pod_addressof_m(structure), static_cast(RFIFOP(s, pos)), sizeof(T)); } inline -IP4Address RFIFOIP(int fd, size_t pos) +IP4Address RFIFOIP(Session *s, size_t pos) { IP4Address o; - RFIFO_STRUCT(fd, pos, o); + RFIFO_STRUCT(s, pos, o); return o; } template inline -VString RFIFO_STRING(int fd, size_t pos) +VString RFIFO_STRING(Session *s, size_t pos) { - const char *const begin = static_cast(RFIFOP(fd, pos)); + const char *const begin = static_cast(RFIFOP(s, pos)); const char *const end = begin + len-1; const char *const mid = std::find(begin, end, '\0'); return XString(begin, mid, nullptr); } inline -FString RFIFO_STRING(int fd, size_t pos, size_t len) +FString RFIFO_STRING(Session *s, size_t pos, size_t len) { - const char *const begin = static_cast(RFIFOP(fd, pos)); + const char *const begin = static_cast(RFIFOP(s, pos)); const char *const end = begin + len; const char *const mid = std::find(begin, end, '\0'); return XString(begin, mid, nullptr); } inline -void RFIFO_BUF_CLONE(int fd, uint8_t *buf, size_t len) +void RFIFO_BUF_CLONE(Session *s, uint8_t *buf, size_t len) { - really_memcpy(buf, static_cast(RFIFOP(fd, 0)), len); + really_memcpy(buf, static_cast(RFIFOP(s, 0)), len); } /// Done reading -void RFIFOSKIP(int fd, size_t len); +void RFIFOSKIP(Session *s, size_t len); /// Read from an arbitrary buffer inline @@ -236,65 +244,65 @@ FString RBUF_STRING(const uint8_t *p, size_t pos, size_t len) /// Unused - check how much data can be written // the existence of this seems scary inline -size_t WFIFOSPACE(int fd) +size_t WFIFOSPACE(Session *s) { - return session[fd]->max_wdata - session[fd]->wdata_size; + return s->max_wdata - s->wdata_size; } /// Write to the queue inline -void *WFIFOP(int fd, size_t pos) +void *WFIFOP(Session *s, size_t pos) { - return &session[fd]->wdata[session[fd]->wdata_size + pos]; + return &s->wdata[s->wdata_size + pos]; } inline -uint8_t& WFIFOB(int fd, size_t pos) +uint8_t& WFIFOB(Session *s, size_t pos) { - return *static_cast(WFIFOP(fd, pos)); + return *static_cast(WFIFOP(s, pos)); } inline -uint16_t& WFIFOW(int fd, size_t pos) +uint16_t& WFIFOW(Session *s, size_t pos) { - return *static_cast(WFIFOP(fd, pos)); + return *static_cast(WFIFOP(s, pos)); } inline -uint32_t& WFIFOL(int fd, size_t pos) +uint32_t& WFIFOL(Session *s, size_t pos) { - return *static_cast(WFIFOP(fd, pos)); + return *static_cast(WFIFOP(s, pos)); } template -void WFIFO_STRUCT(int fd, size_t pos, T& structure) +void WFIFO_STRUCT(Session *s, size_t pos, T& structure) { - really_memcpy(static_cast(WFIFOP(fd, pos)), pod_addressof_c(structure), sizeof(T)); + really_memcpy(static_cast(WFIFOP(s, pos)), pod_addressof_c(structure), sizeof(T)); } inline -IP4Address& WFIFOIP(int fd, size_t pos) +IP4Address& WFIFOIP(Session *s, size_t pos) { static_assert(is_trivially_copyable::value, "That was the whole point"); - return *static_cast(WFIFOP(fd, pos)); + return *static_cast(WFIFOP(s, pos)); } inline -void WFIFO_STRING(int fd, size_t pos, XString s, size_t len) +void WFIFO_STRING(Session *s, size_t pos, XString str, size_t len) { - char *const begin = static_cast(WFIFOP(fd, pos)); + char *const begin = static_cast(WFIFOP(s, pos)); char *const end = begin + len; - char *const mid = std::copy(s.begin(), s.end(), begin); + char *const mid = std::copy(str.begin(), str.end(), begin); std::fill(mid, end, '\0'); } inline -void WFIFO_ZERO(int fd, size_t pos, size_t len) +void WFIFO_ZERO(Session *s, size_t pos, size_t len) { - uint8_t *b = static_cast(WFIFOP(fd, pos)); + uint8_t *b = static_cast(WFIFOP(s, pos)); uint8_t *e = b + len; std::fill(b, e, '\0'); } inline -void WFIFO_BUF_CLONE(int fd, const uint8_t *buf, size_t len) +void WFIFO_BUF_CLONE(Session *s, const uint8_t *buf, size_t len) { - really_memcpy(static_cast(WFIFOP(fd, 0)), buf, len); + really_memcpy(static_cast(WFIFOP(s, 0)), buf, len); } /// Finish writing -void WFIFOSET(int fd, size_t len); +void WFIFOSET(Session *s, size_t len); /// Write to an arbitrary buffer inline @@ -344,10 +352,10 @@ void WBUF_ZERO(uint8_t *p, size_t pos, size_t len) } inline -void RFIFO_WFIFO_CLONE(int rfd, int wfd, size_t len) +void RFIFO_WFIFO_CLONE(Session *rs, Session *ws, size_t len) { - really_memcpy(static_cast(WFIFOP(wfd, 0)), - static_cast(RFIFOP(rfd, 0)), len); + really_memcpy(static_cast(WFIFOP(ws, 0)), + static_cast(RFIFOP(rs, 0)), len); } #endif // SOCKET_HPP -- cgit v1.2.3-70-g09d2