Przeglądaj źródła

More tweaks to socket.c to simplify the code
- 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

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9954 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 18 lat temu
rodzic
commit
5625383530

+ 5 - 0
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

+ 2 - 0
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

+ 1 - 8
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.

+ 1 - 1
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)) {

+ 1 - 1
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

+ 42 - 87
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);

+ 19 - 21
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