diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/socket.c | 199 | ||||
-rw-r--r-- | src/common/socket.h | 36 |
2 files changed, 117 insertions, 118 deletions
diff --git a/src/common/socket.c b/src/common/socket.c index 0b69743ab..098fdf236 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -362,7 +362,7 @@ void set_eof(int fd) // Add this socket to the shortlist for eof handling. send_shortlist_add_fd(fd); #endif - session[fd]->flag.eof = 1; + sockt->session[fd]->flag.eof = 1; } } @@ -373,7 +373,7 @@ int recv_to_fifo(int fd) if (!sockt->session_is_active(fd)) return -1; - len = sRecv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0); + len = sRecv(fd, (char *) sockt->session[fd]->rdata + sockt->session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0); if( len == SOCKET_ERROR ) {//An exception has occurred @@ -390,12 +390,12 @@ int recv_to_fifo(int fd) return 0; } - session[fd]->rdata_size += len; - session[fd]->rdata_tick = sockt->last_tick; + sockt->session[fd]->rdata_size += len; + sockt->session[fd]->rdata_tick = sockt->last_tick; #ifdef SHOW_SERVER_STATS socket_data_i += len; socket_data_qi += len; - if (!session[fd]->flag.server) + if (!sockt->session[fd]->flag.server) { socket_data_ci += len; } @@ -410,19 +410,19 @@ int send_from_fifo(int fd) if (!sockt->session_is_valid(fd)) return -1; - if( session[fd]->wdata_size == 0 ) + if( sockt->session[fd]->wdata_size == 0 ) return 0; // nothing to send - len = sSend(fd, (const char *) session[fd]->wdata, (int)session[fd]->wdata_size, MSG_NOSIGNAL); + len = sSend(fd, (const char *) sockt->session[fd]->wdata, (int)sockt->session[fd]->wdata_size, MSG_NOSIGNAL); if( len == SOCKET_ERROR ) {//An exception has occurred if( sErrno != S_EWOULDBLOCK ) { //ShowDebug("send_from_fifo: %s, ending connection #%d\n", error_msg(), fd); #ifdef SHOW_SERVER_STATS - socket_data_qo -= session[fd]->wdata_size; + socket_data_qo -= sockt->session[fd]->wdata_size; #endif - session[fd]->wdata_size = 0; //Clear the send queue as we can't send anymore. [Skotlex] + sockt->session[fd]->wdata_size = 0; //Clear the send queue as we can't send anymore. [Skotlex] sockt->eof(fd); } return 0; @@ -432,14 +432,14 @@ int send_from_fifo(int fd) { // some data could not be transferred? // shift unsent data to the beginning of the queue - if( (size_t)len < session[fd]->wdata_size ) - memmove(session[fd]->wdata, session[fd]->wdata + len, session[fd]->wdata_size - len); + if( (size_t)len < sockt->session[fd]->wdata_size ) + memmove(sockt->session[fd]->wdata, sockt->session[fd]->wdata + len, sockt->session[fd]->wdata_size - len); - session[fd]->wdata_size -= len; + sockt->session[fd]->wdata_size -= len; #ifdef SHOW_SERVER_STATS socket_data_o += len; socket_data_qo -= len; - if (!session[fd]->flag.server) + if (!sockt->session[fd]->flag.server) { socket_data_co += len; } @@ -452,8 +452,8 @@ int send_from_fifo(int fd) /// Best effort - there's no warranty that the data will be sent. void flush_fifo(int fd) { - if(session[fd] != NULL) - session[fd]->func_send(fd); + if(sockt->session[fd] != NULL) + sockt->session[fd]->func_send(fd); } void flush_fifos(void) @@ -503,7 +503,7 @@ int connect_client(int listen_fd) { sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); - session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr); + sockt->session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr); return fd; } @@ -553,8 +553,8 @@ int make_listen_bind(uint32 ip, uint16 port) sFD_SET(fd, &readfds); create_session(fd, connect_client, null_send, null_parse); - session[fd]->client_addr = 0; // just listens - session[fd]->rdata_tick = 0; // disable timeouts on this socket + sockt->session[fd]->client_addr = 0; // just listens + sockt->session[fd]->rdata_tick = 0; // disable timeouts on this socket return fd; } @@ -604,25 +604,25 @@ int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt) { sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); - session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); + sockt->session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); return fd; } static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse) { - CREATE(session[fd], struct socket_data, 1); - CREATE(session[fd]->rdata, unsigned char, RFIFO_SIZE); - CREATE(session[fd]->wdata, unsigned char, WFIFO_SIZE); - session[fd]->max_rdata = RFIFO_SIZE; - session[fd]->max_wdata = WFIFO_SIZE; - session[fd]->func_recv = func_recv; - session[fd]->func_send = func_send; - session[fd]->func_parse = func_parse; - session[fd]->rdata_tick = sockt->last_tick; - session[fd]->session_data = NULL; - session[fd]->hdata = NULL; - session[fd]->hdatac = 0; + CREATE(sockt->session[fd], struct socket_data, 1); + CREATE(sockt->session[fd]->rdata, unsigned char, RFIFO_SIZE); + CREATE(sockt->session[fd]->wdata, unsigned char, WFIFO_SIZE); + sockt->session[fd]->max_rdata = RFIFO_SIZE; + sockt->session[fd]->max_wdata = WFIFO_SIZE; + sockt->session[fd]->func_recv = func_recv; + sockt->session[fd]->func_send = func_send; + sockt->session[fd]->func_parse = func_parse; + sockt->session[fd]->rdata_tick = sockt->last_tick; + sockt->session[fd]->session_data = NULL; + sockt->session[fd]->hdata = NULL; + sockt->session[fd]->hdatac = 0; return 0; } @@ -630,25 +630,25 @@ static void delete_session(int fd) { if (sockt->session_is_valid(fd)) { #ifdef SHOW_SERVER_STATS - socket_data_qi -= session[fd]->rdata_size - session[fd]->rdata_pos; - socket_data_qo -= session[fd]->wdata_size; + socket_data_qi -= sockt->session[fd]->rdata_size - sockt->session[fd]->rdata_pos; + socket_data_qo -= sockt->session[fd]->wdata_size; #endif - aFree(session[fd]->rdata); - aFree(session[fd]->wdata); - if( session[fd]->session_data ) - aFree(session[fd]->session_data); - if (session[fd]->hdata) { + aFree(sockt->session[fd]->rdata); + aFree(sockt->session[fd]->wdata); + if( sockt->session[fd]->session_data ) + aFree(sockt->session[fd]->session_data); + if (sockt->session[fd]->hdata) { unsigned int i; - for(i = 0; i < session[fd]->hdatac; i++) { - if( session[fd]->hdata[i]->flag.free ) { - aFree(session[fd]->hdata[i]->data); + for(i = 0; i < sockt->session[fd]->hdatac; i++) { + if( sockt->session[fd]->hdata[i]->flag.free ) { + aFree(sockt->session[fd]->hdata[i]->data); } - aFree(session[fd]->hdata[i]); + aFree(sockt->session[fd]->hdata[i]); } - aFree(session[fd]->hdata); + aFree(sockt->session[fd]->hdata); } - aFree(session[fd]); - session[fd] = NULL; + aFree(sockt->session[fd]); + sockt->session[fd] = NULL; } } @@ -657,14 +657,14 @@ int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size) if (!sockt->session_is_valid(fd)) return 0; - if( session[fd]->max_rdata != rfifo_size && session[fd]->rdata_size < rfifo_size) { - RECREATE(session[fd]->rdata, unsigned char, rfifo_size); - session[fd]->max_rdata = rfifo_size; + if( sockt->session[fd]->max_rdata != rfifo_size && sockt->session[fd]->rdata_size < rfifo_size) { + RECREATE(sockt->session[fd]->rdata, unsigned char, rfifo_size); + sockt->session[fd]->max_rdata = rfifo_size; } - if( session[fd]->max_wdata != wfifo_size && session[fd]->wdata_size < wfifo_size) { - RECREATE(session[fd]->wdata, unsigned char, wfifo_size); - session[fd]->max_wdata = wfifo_size; + if( sockt->session[fd]->max_wdata != wfifo_size && sockt->session[fd]->wdata_size < wfifo_size) { + RECREATE(sockt->session[fd]->wdata, unsigned char, wfifo_size); + sockt->session[fd]->max_wdata = wfifo_size; } return 0; } @@ -676,22 +676,22 @@ int realloc_writefifo(int fd, size_t addition) if (!sockt->session_is_valid(fd)) // might not happen return 0; - if (session[fd]->wdata_size + addition > session[fd]->max_wdata) { + if (sockt->session[fd]->wdata_size + addition > sockt->session[fd]->max_wdata) { // grow rule; grow in multiples of WFIFO_SIZE newsize = WFIFO_SIZE; - while( session[fd]->wdata_size + addition > newsize ) newsize += WFIFO_SIZE; - } else if (session[fd]->max_wdata >= (size_t)2*(session[fd]->flag.server?FIFOSIZE_SERVERLINK:WFIFO_SIZE) - && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata + while( sockt->session[fd]->wdata_size + addition > newsize ) newsize += WFIFO_SIZE; + } else if (sockt->session[fd]->max_wdata >= (size_t)2*(sockt->session[fd]->flag.server?FIFOSIZE_SERVERLINK:WFIFO_SIZE) + && (sockt->session[fd]->wdata_size+addition)*4 < sockt->session[fd]->max_wdata ) { // shrink rule, shrink by 2 when only a quarter of the fifo is used, don't shrink below nominal size. - newsize = session[fd]->max_wdata / 2; + newsize = sockt->session[fd]->max_wdata / 2; } else { // no change return 0; } - RECREATE(session[fd]->wdata, unsigned char, newsize); - session[fd]->max_wdata = newsize; + RECREATE(sockt->session[fd]->wdata, unsigned char, newsize); + sockt->session[fd]->max_wdata = newsize; return 0; } @@ -704,7 +704,7 @@ int rfifoskip(int fd, size_t len) if (!sockt->session_is_active(fd)) return 0; - s = session[fd]; + s = sockt->session[fd]; if (s->rdata_size < s->rdata_pos + len) { ShowError("RFIFOSKIP: skipped past end of read buffer! Adjusting from %"PRIuS" to %"PRIuS" (session #%d)\n", len, RFIFOREST(fd), fd); @@ -722,7 +722,7 @@ int rfifoskip(int fd, size_t len) int wfifoset(int fd, size_t len) { size_t newreserve; - struct socket_data* s = session[fd]; + struct socket_data* s = sockt->session[fd]; if (!sockt->session_is_valid(fd) || s->wdata == NULL) return 0; @@ -797,11 +797,11 @@ int do_sockets(int next) #else for (i = 1; i < sockt->fd_max; i++) { - if(!session[i]) + if(!sockt->session[fd] continue; - if(session[i]->wdata_size) - session[i]->func_send(i); + if(sockt->session[fd]>wdata_size) + sockt->session[fd]>func_send(i); } #endif @@ -829,16 +829,16 @@ int do_sockets(int next) for( i = 0; i < (int)rfd.fd_count; ++i ) { int fd = sock2fd(rfd.fd_array[i]); - if( session[fd] ) - session[fd]->func_recv(fd); + if( sockt->session[fd] ) + sockt->session[fd]->func_recv(fd); } #else // otherwise assume that the fd_set is a bit-array and enumerate it in a standard way for( i = 1; ret && i < sockt->fd_max; ++i ) { - if(sFD_ISSET(i,&rfd) && session[i]) + if(sFD_ISSET(i,&rfd) && sockt->session[i]) { - session[i]->func_recv(i); + sockt->session[i]->func_recv(i); --ret; } } @@ -850,15 +850,15 @@ int do_sockets(int next) #else for (i = 1; i < sockt->fd_max; i++) { - if(!session[i]) + if(!sockt->session[i]) continue; - if(session[i]->wdata_size) - session[i]->func_send(i); + if(sockt->session[i]->wdata_size) + sockt->session[i]->func_send(i); - if (session[i]->flag.eof) { //func_send can't free a session, this is safe. + if (sockt->session[i]->flag.eof) { //func_send can't free a session, this is safe. //Finally, even if there is no data to parse, connections signaled eof should be closed, so we call parse_func [Skotlex] - session[i]->func_parse(i); //This should close the session immediately. + sockt->session[i]->func_parse(i); //This should close the session immediately. } } #endif @@ -866,13 +866,13 @@ int do_sockets(int next) // parse input data on each socket for(i = 1; i < sockt->fd_max; i++) { - if(!session[i]) + if(!sockt->session[i]) continue; - if (session[i]->rdata_tick && DIFF_TICK(sockt->last_tick, session[i]->rdata_tick) > sockt->stall_time) { - if( session[i]->flag.server ) {/* server is special */ - if( session[i]->flag.ping != 2 )/* only update if necessary otherwise it'd resend the ping unnecessarily */ - session[i]->flag.ping = 1; + if (sockt->session[i]->rdata_tick && DIFF_TICK(sockt->last_tick, sockt->session[i]->rdata_tick) > sockt->stall_time) { + if( sockt->session[i]->flag.server ) {/* server is special */ + if( sockt->session[i]->flag.ping != 2 )/* only update if necessary otherwise it'd resend the ping unnecessarily */ + sockt->session[i]->flag.ping = 1; } else { ShowInfo("Session #%d timed out\n", i); sockt->eof(i); @@ -881,16 +881,16 @@ int do_sockets(int next) #ifdef __clang_analyzer__ // Let Clang's static analyzer know this never happens (it thinks it might because of a NULL check in session_is_valid) - if (!session[i]) continue; + if (!sockt->session[i]) continue; #endif // __clang_analyzer__ - session[i]->func_parse(i); + sockt->session[i]->func_parse(i); - if(!session[i]) + if(!sockt->session[i]) continue; RFIFOFLUSH(i); // after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed) - if (session[i]->rdata_size == session[i]->max_rdata) { + if (sockt->session[i]->rdata_size == sockt->session[i]->max_rdata) { sockt->eof(i); continue; } @@ -1217,15 +1217,15 @@ void socket_final(void) #endif for( i = 1; i < sockt->fd_max; i++ ) - if(session[i]) + if(sockt->session[i]) sockt->close(i); - // session[0] - aFree(session[0]->rdata); - aFree(session[0]->wdata); - aFree(session[0]); + // sockt->session[0] + aFree(sockt->session[0]->rdata); + aFree(sockt->session[0]->wdata); + aFree(sockt->session[0]); - aFree(session); + aFree(sockt->session); if (sockt->lan_subnet) aFree(sockt->lan_subnet); @@ -1253,7 +1253,7 @@ void socket_close(int fd) sFD_CLR(fd, &readfds);// this needs to be done before closing the socket sShutdown(fd, SHUT_RDWR); // Disallow further reads/writes sClose(fd); // We don't really care if these closing functions return an error, we are just shutting down and not reusing this socket. - if (session[fd]) delete_session(fd); + if (sockt->session[fd]) delete_session(fd); } /// Retrieve local ips in host byte order. @@ -1397,14 +1397,14 @@ void socket_init(void) memset(send_shortlist_set, 0, sizeof(send_shortlist_set)); #endif - CREATE(session, struct socket_data *, FD_SETSIZE); + CREATE(sockt->session, struct socket_data *, FD_SETSIZE); socket_config_read(SOCKET_CONF_FILENAME); // initialize last send-receive tick sockt->last_tick = time(NULL); - // session[0] is now currently used for disconnected sessions of the map server, and as such, + // sockt->session[0] is now currently used for disconnected sessions of the map server, and as such, // should hold enough buffer (it is a vacuum so to speak) as it is never flushed. [Skotlex] create_session(0, null_recv, null_send, null_parse); @@ -1416,19 +1416,16 @@ void socket_init(void) #endif ShowInfo("Server supports up to '"CL_WHITE"%"PRId64""CL_RESET"' concurrent connections.\n", rlim_cur); - - /* Hercules Plugin Manager */ - HPM->share(session,"session"); } bool session_is_valid(int fd) { - return ( fd > 0 && fd < FD_SETSIZE && session[fd] != NULL ); + return ( fd > 0 && fd < FD_SETSIZE && sockt->session[fd] != NULL ); } bool session_is_active(int fd) { - return ( sockt->session_is_valid(fd) && !session[fd]->flag.eof ); + return ( sockt->session_is_valid(fd) && !sockt->session[fd]->flag.eof ); } // Resolves hostname into a numeric ip. @@ -1588,20 +1585,20 @@ void send_shortlist_do_sends() send_shortlist_set[idx]&=~(1<<bit);// unset fd // If this session still exists, perform send operations on it and // check for the eof state. - if( session[fd] ) + if( sockt->session[fd] ) { // Send data - if( session[fd]->wdata_size ) - session[fd]->func_send(fd); + if( sockt->session[fd]->wdata_size ) + sockt->session[fd]->func_send(fd); // If it's been marked as eof, call the parse func on it so that // the socket will be immediately closed. - if( session[fd]->flag.eof ) - session[fd]->func_parse(fd); + if( sockt->session[fd]->flag.eof ) + sockt->session[fd]->func_parse(fd); // If the session still exists, is not eof and has things left to // be sent from it we'll re-add it to the shortlist. - if( session[fd] && !session[fd]->flag.eof && session[fd]->wdata_size ) + if( sockt->session[fd] && !sockt->session[fd]->flag.eof && sockt->session[fd]->wdata_size ) send_shortlist_add_fd(fd); } } diff --git a/src/common/socket.h b/src/common/socket.h index e7046b0d1..18bf25178 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -23,9 +23,14 @@ struct HPluginData; // socket I/O macros #define RFIFOHEAD(fd) -#define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) sockt->realloc_writefifo((fd), (size)); }while(0) -#define RFIFOP(fd,pos) (session[fd]->rdata + session[fd]->rdata_pos + (pos)) -#define WFIFOP(fd,pos) (session[fd]->wdata + session[fd]->wdata_size + (pos)) +#define WFIFOHEAD(fd, size) \ + do{ \ + if ((fd) && sockt->session[fd]->wdata_size + (size) > sockt->session[fd]->max_wdata) \ + sockt->realloc_writefifo((fd), (size)); \ + } while(0) + +#define RFIFOP(fd,pos) (sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos + (pos)) +#define WFIFOP(fd,pos) (sockt->session[fd]->wdata + sockt->session[fd]->wdata_size + (pos)) #define RFIFOB(fd,pos) (*(uint8*)RFIFOP((fd),(pos))) #define WFIFOB(fd,pos) (*(uint8*)WFIFOP((fd),(pos))) @@ -35,18 +40,18 @@ struct HPluginData; #define WFIFOL(fd,pos) (*(uint32*)WFIFOP((fd),(pos))) #define RFIFOQ(fd,pos) (*(uint64*)RFIFOP((fd),(pos))) #define WFIFOQ(fd,pos) (*(uint64*)WFIFOP((fd),(pos))) -#define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size) -#define WFIFOSPACE(fd) (session[fd]->max_wdata - session[fd]->wdata_size) +#define RFIFOSPACE(fd) (sockt->session[fd]->max_rdata - sockt->session[fd]->rdata_size) +#define WFIFOSPACE(fd) (sockt->session[fd]->max_wdata - sockt->session[fd]->wdata_size) -#define RFIFOREST(fd) (session[fd]->flag.eof ? 0 : session[fd]->rdata_size - session[fd]->rdata_pos) +#define RFIFOREST(fd) (sockt->session[fd]->flag.eof ? 0 : sockt->session[fd]->rdata_size - sockt->session[fd]->rdata_pos) #define RFIFOFLUSH(fd) \ do { \ - if(session[fd]->rdata_size == session[fd]->rdata_pos){ \ - session[fd]->rdata_size = session[fd]->rdata_pos = 0; \ + if(sockt->session[fd]->rdata_size == sockt->session[fd]->rdata_pos){ \ + sockt->session[fd]->rdata_size = sockt->session[fd]->rdata_pos = 0; \ } else { \ - session[fd]->rdata_size -= session[fd]->rdata_pos; \ - memmove(session[fd]->rdata, session[fd]->rdata+session[fd]->rdata_pos, session[fd]->rdata_size); \ - session[fd]->rdata_pos = 0; \ + sockt->session[fd]->rdata_size -= sockt->session[fd]->rdata_pos; \ + memmove(sockt->session[fd]->rdata, sockt->session[fd]->rdata+sockt->session[fd]->rdata_pos, sockt->session[fd]->rdata_size); \ + sockt->session[fd]->rdata_pos = 0; \ } \ } while(0) @@ -54,7 +59,7 @@ struct HPluginData; #define RFIFOSKIP(fd, len) (sockt->rfifoskip(fd, len)) /* [Ind/Hercules] */ -#define RFIFO2PTR(fd) (void*)(session[fd]->rdata + session[fd]->rdata_pos) +#define RFIFO2PTR(fd) (void*)(sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos) // buffer I/O macros #define RBUFP(p,pos) (((uint8*)(p)) + (pos)) @@ -127,11 +132,6 @@ struct s_subnet { #define MAKEIP(a,b,c,d) ((uint32)( ( ( (a)&0xFF ) << 24 ) | ( ( (b)&0xFF ) << 16 ) | ( ( (c)&0xFF ) << 8 ) | ( ( (d)&0xFF ) << 0 ) )) /** - * This stays out of the interface. - **/ -struct socket_data **session; - -/** * Socket.c interface, mostly for reading however. **/ struct socket_interface { @@ -143,6 +143,8 @@ struct socket_interface { uint32 addr_[16]; // ip addresses of local host (host byte order) int naddr_; // # of ip addresses + struct socket_data **session; + struct s_subnet *lan_subnet; ///< LAN subnets array int lan_subnet_count; ///< LAN subnets count struct s_subnet *trusted_ip; ///< Trusted IP ranges array |