summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-02-03 10:05:00 -0800
committerBen Longbons <b.r.longbons@gmail.com>2014-02-04 12:22:33 -0800
commit9544985ccbb20d7f8377c63a4e59d1ff97b844ac (patch)
tree764351426278353e63f3ca7e3c25c6cf01427311 /src/common
parentc39691d2f3852e81c0cfd49331e01a0e263591e2 (diff)
downloadtmwa-9544985ccbb20d7f8377c63a4e59d1ff97b844ac.tar.gz
tmwa-9544985ccbb20d7f8377c63a4e59d1ff97b844ac.tar.bz2
tmwa-9544985ccbb20d7f8377c63a4e59d1ff97b844ac.tar.xz
tmwa-9544985ccbb20d7f8377c63a4e59d1ff97b844ac.zip
Convert fd to Session* where meaningful
Diffstat (limited to 'src/common')
-rw-r--r--src/common/socket.cpp197
-rw-r--r--src/common/socket.hpp120
2 files changed, 164 insertions, 153 deletions
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<std::unique_ptr<struct socket_data>, FD_SETSIZE> session;
+std::array<std::unique_ptr<Session>, 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<struct sockaddr *>(&client_address), &len);
+ int fd = accept(ls->fd, reinterpret_cast<struct sockaddr *>(&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<socket_data>();
- 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>();
+ 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<socket_data>();
+ session[fd] = make_unique<Session>();
+ 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<socket_data>();
- 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>();
+ 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<socket_data>& 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<socket_data>& 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<time_t>(TimeT::now()) - static_cast<time_t>(session[i]->created) > CONNECT_TIMEOUT)
+ if (!s->connected
+ && static_cast<time_t>(TimeT::now()) - static_cast<time_t>(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<socket_data>& 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<SessionData, SessionDeleter> 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<std::unique_ptr<socket_data>, FD_SETSIZE> session;
+extern std::array<std::unique_ptr<Session>, 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<class T>
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<const uint8_t *>(RFIFOP(fd, pos));
+ return *static_cast<const uint8_t *>(RFIFOP(s, pos));
}
inline
-uint16_t RFIFOW(int fd, size_t pos)
+uint16_t RFIFOW(Session *s, size_t pos)
{
- return *static_cast<const uint16_t *>(RFIFOP(fd, pos));
+ return *static_cast<const uint16_t *>(RFIFOP(s, pos));
}
inline
-uint32_t RFIFOL(int fd, size_t pos)
+uint32_t RFIFOL(Session *s, size_t pos)
{
- return *static_cast<const uint32_t *>(RFIFOP(fd, pos));
+ return *static_cast<const uint32_t *>(RFIFOP(s, pos));
}
template<class T>
-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<const uint8_t *>(RFIFOP(fd, pos)), sizeof(T));
+ really_memcpy(pod_addressof_m(structure), static_cast<const uint8_t *>(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<uint8_t len>
inline
-VString<len-1> RFIFO_STRING(int fd, size_t pos)
+VString<len-1> RFIFO_STRING(Session *s, size_t pos)
{
- const char *const begin = static_cast<const char *>(RFIFOP(fd, pos));
+ const char *const begin = static_cast<const char *>(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<const char *>(RFIFOP(fd, pos));
+ const char *const begin = static_cast<const char *>(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<const uint8_t *>(RFIFOP(fd, 0)), len);
+ really_memcpy(buf, static_cast<const uint8_t *>(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<uint8_t *>(WFIFOP(fd, pos));
+ return *static_cast<uint8_t *>(WFIFOP(s, pos));
}
inline
-uint16_t& WFIFOW(int fd, size_t pos)
+uint16_t& WFIFOW(Session *s, size_t pos)
{
- return *static_cast<uint16_t *>(WFIFOP(fd, pos));
+ return *static_cast<uint16_t *>(WFIFOP(s, pos));
}
inline
-uint32_t& WFIFOL(int fd, size_t pos)
+uint32_t& WFIFOL(Session *s, size_t pos)
{
- return *static_cast<uint32_t *>(WFIFOP(fd, pos));
+ return *static_cast<uint32_t *>(WFIFOP(s, pos));
}
template<class T>
-void WFIFO_STRUCT(int fd, size_t pos, T& structure)
+void WFIFO_STRUCT(Session *s, size_t pos, T& structure)
{
- really_memcpy(static_cast<uint8_t *>(WFIFOP(fd, pos)), pod_addressof_c(structure), sizeof(T));
+ really_memcpy(static_cast<uint8_t *>(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<IP4Address>::value, "That was the whole point");
- return *static_cast<IP4Address *>(WFIFOP(fd, pos));
+ return *static_cast<IP4Address *>(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<char *>(WFIFOP(fd, pos));
+ char *const begin = static_cast<char *>(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<uint8_t *>(WFIFOP(fd, pos));
+ uint8_t *b = static_cast<uint8_t *>(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<uint8_t *>(WFIFOP(fd, 0)), buf, len);
+ really_memcpy(static_cast<uint8_t *>(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<uint8_t *>(WFIFOP(wfd, 0)),
- static_cast<const uint8_t *>(RFIFOP(rfd, 0)), len);
+ really_memcpy(static_cast<uint8_t *>(WFIFOP(ws, 0)),
+ static_cast<const uint8_t *>(RFIFOP(rs, 0)), len);
}
#endif // SOCKET_HPP