diff options
-rw-r--r-- | Changelog-Trunk.txt | 5 | ||||
-rw-r--r-- | conf-tmpl/Changelog.txt | 2 | ||||
-rw-r--r-- | conf-tmpl/packet_athena.conf | 9 | ||||
-rw-r--r-- | src/char/char.c | 2 | ||||
-rw-r--r-- | src/char_sql/char.c | 2 | ||||
-rw-r--r-- | src/common/socket.c | 129 | ||||
-rw-r--r-- | src/common/socket.h | 40 |
7 files changed, 71 insertions, 118 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index fb7550a4c..1f43427a8 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/03/05 + * More tweaks to socket.c to simplify the code [ultramage] + - many generic cleanups - reformatting, useless code removal, etc + - made the mode_neg setting a compile-time decision, not a run-time one + - removed the silly frame_size setting (there since r1) + - added some TODOs to http://www.eathena.ws/board/index.php?showtopic=127988 * Added the +20hit that were missing the NPC elemental attack skills. * Added support for autospells using "a random skill level". The last value of bonus4 bAutoSpell is used for determining this as well as the target. &1 diff --git a/conf-tmpl/Changelog.txt b/conf-tmpl/Changelog.txt index b42e0d9de..d05ae8ae5 100644 --- a/conf-tmpl/Changelog.txt +++ b/conf-tmpl/Changelog.txt @@ -1,4 +1,6 @@ Date Added +2007/03/05 + * Removed mode_neg and frame_size from packet_athena.conf [ultramage] 2007/02/16 * Collapsed config settings "sg_miracle_skill_min_duration" and "sg_miracle_skill_max_duration" into "sg_miracle_skill_duration", which diff --git a/conf-tmpl/packet_athena.conf b/conf-tmpl/packet_athena.conf index 22d44c1d1..19807999d 100644 --- a/conf-tmpl/packet_athena.conf +++ b/conf-tmpl/packet_athena.conf @@ -2,19 +2,12 @@ // translated (davidsiaw) -// Display debug reports (iWhen something goes wrong during the report, the report is saved.) +// Display debug reports (When something goes wrong during the report, the report is saved.) debug: no // How long can a socket stall before closing the connection (in seconds) stall_time: 60 -// When enabled, sets TCP_NODELAY (disable nagel Algorythm) on all connections -mode_neg: yes - -// frame packet size as considered by the server (when there's enough -// information in queue to fill the frame_size, a "send" is forced) -//frame_size: 1054 - //----- IP Rules Settings ----- // If IP's are checked when connecting. diff --git a/src/char/char.c b/src/char/char.c index 2f6c0e2f5..22dd81d94 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2722,7 +2722,7 @@ int parse_frommap(int fd) { return 0; } - while(RFIFOREST(fd) >= 2 && !session[fd]->eof) { + while(RFIFOREST(fd) >= 2) { //ShowDebug("Received packet 0x%4x (%d bytes) from map-server (connection %d)\n", RFIFOW(fd, 0), RFIFOREST(fd), fd); switch(RFIFOW(fd,0)) { diff --git a/src/char_sql/char.c b/src/char_sql/char.c index a9a90e228..a301bb46f 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -2478,7 +2478,7 @@ int parse_frommap(int fd) { return 0; } - while(RFIFOREST(fd) >= 2 && !session[fd]->eof) { + while(RFIFOREST(fd) >= 2) { switch(RFIFOW(fd, 0)) { // map-server alive packet diff --git a/src/common/socket.c b/src/common/socket.c index fda81521d..87c98f645 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -3,6 +3,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #ifdef __WIN32 @@ -51,9 +52,6 @@ #define S_ECONNABORTED ECONNABORTED #endif -#include <fcntl.h> -#include <string.h> - #include "../common/socket.h" #include "../common/mmo.h" #include "../common/timer.h" @@ -64,17 +62,11 @@ fd_set readfds; int fd_max; time_t last_tick; time_t stall_time = 60; -int ip_rules = 1; uint32 addr_[16]; // ip addresses of local host (host byte order) int naddr_ = 0; // # of ip addresses -#ifndef TCP_FRAME_LEN -#define TCP_FRAME_LEN 1024 -#endif - -static int mode_neg=1; -static size_t frame_size=TCP_FRAME_LEN; +#define MODE_NODELAY 1 // disables|enables packet buffering // values derived from freya // a player that send more than 2k is probably a hacker without be parsed @@ -82,45 +74,26 @@ static size_t frame_size=TCP_FRAME_LEN; size_t rfifo_size = (16*1024); size_t wfifo_size = (16*1024); -#define CONVIP(ip) ip&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,ip>>24 - -struct socket_data *session[FD_SETSIZE]; +struct socket_data* session[FD_SETSIZE]; int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse); #ifndef MINICORE -static int connect_check(unsigned int ip); -#else - #define connect_check(n) 1 + int ip_rules = 1; + static int connect_check(unsigned int ip); #endif + /*====================================== * CORE : Default processing functions *--------------------------------------*/ -int null_recv(int fd); -int null_send(int fd); -int null_parse(int fd); - -int null_recv(int fd) -{ - return 0; -} +int null_recv(int fd) { return 0; } +int null_send(int fd) { return 0; } +int null_parse(int fd) { return 0; } -int null_send(int fd) -{ - return 0; -} +ParseFunc default_func_parse = null_parse; -int null_parse(int fd) -{ - //ShowMessage("null_parse : %d\n",fd); - session[fd]->rdata_pos = session[fd]->rdata_size; //RFIFOSKIP(fd, RFIFOREST(fd)); simplify calculation - return 0; -} - -int (*default_func_parse)(int fd) = null_parse; - -void set_defaultparse(int (*defaultparse)(int fd)) +void set_defaultparse(ParseFunc defaultparse) { default_func_parse = defaultparse; } @@ -132,7 +105,7 @@ void set_defaultparse(int (*defaultparse)(int fd)) void set_nonblocking(int fd, int yes) { // TCP_NODELAY BOOL Disables the Nagle algorithm for send coalescing. - if(mode_neg) + if(MODE_NODELAY) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof yes); // FIONBIO Use with a nonzero argp parameter to enable the nonblocking mode of socket s. @@ -141,7 +114,7 @@ void set_nonblocking(int fd, int yes) ShowError("Couldn't set the socket to non-blocking mode (code %d)!\n", s_errno); } -static void setsocketopts(int fd) +void setsocketopts(int fd) { int yes = 1; // reuse fix #ifndef WIN32 @@ -153,7 +126,7 @@ static void setsocketopts(int fd) setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes)); #endif #endif - setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof(yes)); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)); // setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &wfifo_size , sizeof(rfifo_size )); // setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &rfifo_size , sizeof(rfifo_size )); @@ -170,15 +143,14 @@ static void setsocketopts(int fd) /*====================================== * CORE : Socket Sub Function - *-------------------------------------- - */ -static void set_eof(int fd) -{ //Marks a connection eof and invokes the parse_function to disconnect it right away. [Skotlex] + *--------------------------------------*/ +void set_eof(int fd) +{ if (session_isActive(fd)) session[fd]->eof = 1; } -static int recv_to_fifo(int fd) +int recv_to_fifo(int fd) { int len; @@ -199,7 +171,7 @@ static int recv_to_fifo(int fd) return 0; } - if (len <= 0) { //Normal connection end. + if (len == 0) { //Normal connection end. set_eof(fd); return 0; } @@ -209,7 +181,7 @@ static int recv_to_fifo(int fd) return 0; } -static int send_from_fifo(int fd) +int send_from_fifo(int fd) { int len; @@ -248,16 +220,15 @@ static 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 == send_from_fifo) - send_from_fifo(fd); + if(session[fd] != NULL) + session[fd]->func_send(fd); } void flush_fifos(void) { int i; for(i = 1; i < fd_max; i++) - if(session[i] != NULL && session[i]->func_send == send_from_fifo) - send_from_fifo(i); + flush_fifo(i); } /*====================================== @@ -280,11 +251,14 @@ int connect_client(int listen_fd) setsocketopts(fd); set_nonblocking(fd, 1); +#ifndef MINICORE if( ip_rules && !connect_check(*(uint32*)(&client_address.sin_addr)) ){ do_close(fd); return -1; - } else - FD_SET(fd,&readfds); + } +#endif + + FD_SET(fd,&readfds); if( fd_max <= fd ) fd_max = fd + 1; @@ -340,11 +314,6 @@ int make_listen_bind(long ip,int port) return fd; } -int make_listen_port(int port) -{ - return make_listen_bind(INADDR_ANY,port); -} - int make_connection(long ip, int port) { struct sockaddr_in server_address; @@ -443,7 +412,7 @@ int realloc_writefifo(int fd, size_t addition) newsize = wfifo_size; while( session[fd]->wdata_size + addition > newsize ) newsize += newsize; } - else if( session[fd]->max_wdata>=FIFOSIZE_SERVERLINK) { + else if( session[fd]->max_wdata >= FIFOSIZE_SERVERLINK) { //Inter-server adjust. [Skotlex] if ((session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata) newsize = session[fd]->max_wdata/2; @@ -507,10 +476,6 @@ int WFIFOSET(int fd, int len) // For inter-server connections, let the reserve be 1/4th of the link size. newreserve = s->wdata_size + (s->max_wdata >= FIFOSIZE_SERVERLINK ? FIFOSIZE_SERVERLINK / 4 : wfifo_size); - if(s->wdata_size >= frame_size) - send_from_fifo(fd); - - // realloc after sending // readfifo does not need to be realloced at all // Even the inter-server buffer may need reallocating! [Skotlex] realloc_writefifo(fd, newreserve); @@ -619,23 +584,21 @@ int do_sendrecv(int next) int do_parsepacket(void) { int i; - struct socket_data *sd; for(i = 1; i < fd_max; i++) { - sd = session[i]; - if(!sd) + if(!session[i]) continue; - if (sd->rdata_tick && DIFF_TICK(last_tick,sd->rdata_tick) > stall_time) { + + if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) { ShowInfo ("Session #%d timed out\n", i); - sd->eof = 1; + session[i]->eof = 1; } - if(sd->rdata_size == 0 && sd->eof == 0) - continue; - sd->func_parse(i); + session[i]->func_parse(i); if(!session[i]) continue; + /* 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 == rfifo_size && session[i]->max_rdata == rfifo_size) { session[i]->eof = 1; @@ -683,6 +646,8 @@ static int ddos_autoreset = 10*60*1000; /// The array's index for any ip is ip&0xFFFF static ConnectHistory* connect_history[0x10000]; +#define CONVIP(ip) ip&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,ip>>24 + static int connect_check_(uint32 ip); /// Verifies if the IP can connect. (with debug info) @@ -690,9 +655,8 @@ static int connect_check_(uint32 ip); static int connect_check(uint32 ip) { int result = connect_check_(ip); - if( access_debug ){ - ShowMessage("connect_check: Connection from %d.%d.%d.%d %s\n", - CONVIP(ip),result ? "allowed." : "denied!"); + if( access_debug ) { + ShowMessage("connect_check: Connection from %d.%d.%d.%d %s\n", CONVIP(ip),result ? "allowed." : "denied!"); } return result; } @@ -905,7 +869,7 @@ int socket_config_read(const char *cfgName) { continue; if(strcmpi(w1,"stall_time")==0){ stall_time = atoi(w2); - #ifndef MINICORE +#ifndef MINICORE } else if( strcmpi(w1,"enable_ip_rules") == 0 ){ if( strcmpi(w2,"yes") == 0 ) ip_rules = 1; @@ -946,17 +910,8 @@ int socket_config_read(const char *cfgName) { access_debug = 0; else access_debug = atoi(w2); - #endif - } else if (strcmpi(w1, "mode_neg") == 0) - { - if(strcmpi(w2,"yes")==0) - mode_neg = 1; - else if(strcmpi(w2,"no")==0) - mode_neg = 0; - else mode_neg = atoi(w2); - } else if (strcmpi(w1, "frame_size") == 0) - frame_size = (size_t)strtoul(w2, NULL, 10); - else if (strcmpi(w1, "import") == 0) +#endif + } else if (strcmpi(w1, "import") == 0) socket_config_read(w2); } fclose(fp); diff --git a/src/common/socket.h b/src/common/socket.h index 0c96edb20..ac1f71568 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -16,22 +16,32 @@ #include "../common/cbasetypes.h" #include <time.h> -// define declaration +// socket I/O macros #ifdef TURBO #define RFIFOVAR(fd) rbPtr ## fd +#define WFIFOVAR(fd) wbPtr ## fd #define RFIFOHEAD(fd) uint8 *RFIFOVAR(fd) = session[fd]->rdata+session[fd]->rdata_pos +#define WFIFOHEAD(fd, x) uint8 *WFIFOVAR(fd) = ( (fd) > 0 && session[fd] ? session[fd]->wdata+session[fd]->wdata_size : NULL ) #define RFIFOP(fd,pos) ( &RFIFOVAR(fd) + (pos) ) +#define WFIFOP(fd,pos) ( &WFIFOVAR(fd) + (pos) ) #else #define RFIFOHEAD(fd) +#define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) 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)) #endif + #define RFIFOB(fd,pos) (*(uint8*)RFIFOP(fd,pos)) +#define WFIFOB(fd,pos) (*(uint8*)WFIFOP(fd,pos)) #define RFIFOW(fd,pos) (*(uint16*)RFIFOP(fd,pos)) +#define WFIFOW(fd,pos) (*(uint16*)WFIFOP(fd,pos)) #define RFIFOL(fd,pos) (*(uint32*)RFIFOP(fd,pos)) +#define WFIFOL(fd,pos) (*(uint32*)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 RFIFOREST(fd) (session[fd]->rdata_size - session[fd]->rdata_pos) -//#define RFIFOSKIP(fd,len) ((session[fd]->rdata_size - session[fd]->rdata_pos - (len) < 0) ? (fprintf(stderr,"too many skip\n"),exit(1)) : (session[fd]->rdata_pos += (len))) #define RFIFOFLUSH(fd) \ do { \ if(session[fd]->rdata_size == session[fd]->rdata_pos){ \ @@ -42,28 +52,17 @@ session[fd]->rdata_pos = 0; \ } \ } while(0) + +// buffer I/O macros #define RBUFP(p,pos) (((uint8*)(p)) + (pos)) #define RBUFB(p,pos) (*(uint8*)RBUFP((p),(pos))) #define RBUFW(p,pos) (*(uint16*)RBUFP((p),(pos))) #define RBUFL(p,pos) (*(uint32*)RBUFP((p),(pos))) -#ifdef TURBO -#define WFIFOVAR(fd) wbPtr ## fd -#define WFIFOHEAD(fd, x) uint8 *WFIFOVAR(fd) = ( (fd) > 0 && session[fd] ? session[fd]->wdata+session[fd]->wdata_size : NULL ) -#define WFIFOP(fd,pos) ( &WFIFOVAR(fd) + (pos) ) -#else -#define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo(fd, size); }while(0) -#define WFIFOP(fd,pos) (session[fd]->wdata+session[fd]->wdata_size+(pos)) -#endif -#define WFIFOB(fd,pos) (*(uint8*)WFIFOP(fd,pos)) -#define WFIFOW(fd,pos) (*(uint16*)WFIFOP(fd,pos)) -#define WFIFOL(fd,pos) (*(uint32*)WFIFOP(fd,pos)) -#define WFIFOSPACE(fd) (session[fd]->max_wdata-session[fd]->wdata_size) -//#define WFIFOSET(fd,len) (session[fd]->wdata_size = (session[fd]->wdata_size + (len) + 2048 < session[fd]->max_wdata) ? session[fd]->wdata_size + len : session[fd]->wdata_size) #define WBUFP(p,pos) (((uint8*)(p)) + (pos)) -#define WBUFB(p,pos) (*(uint8*)((p) + (pos))) -#define WBUFW(p,pos) (*(uint16*)((p) + (pos))) -#define WBUFL(p,pos) (*(uint32*)((p) + (pos))) +#define WBUFB(p,pos) (*(uint8*)WBUFP((p),(pos))) +#define WBUFW(p,pos) (*(uint16*)WBUFP((p),(pos))) +#define WBUFL(p,pos) (*(uint32*)WBUFP((p),(pos))) #define TOB(n) ((uint8)((n)&UINT8_MAX)) #define TOW(n) ((uint16)((n)&UINT16_MAX)) @@ -92,7 +91,7 @@ struct socket_data { // Data prototype declaration -extern struct socket_data *session[FD_SETSIZE]; +extern struct socket_data* session[FD_SETSIZE]; extern int fd_max; @@ -107,7 +106,6 @@ extern int session_isActive(int fd); // Function prototype declaration -int make_listen_port(int); int make_listen_bind(long,int); int make_connection(long,int); int delete_session(int fd); @@ -126,7 +124,7 @@ extern void flush_fifo(int fd); extern void flush_fifos(void); extern void set_nonblocking(int fd, int yes); -void set_defaultparse(int (*defaultparse)(int)); +void set_defaultparse(ParseFunc defaultparse); //Resolves the hostname and stores the string representation of the string in ip. //Meant to simplify calls to gethostbyname without the need of all the |