summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-03-04 21:06:28 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-03-04 21:06:28 +0000
commit4a07e75620d853ff61c5f29330eae86b2c1cb888 (patch)
tree1451bc6c6e5bea83fcf1a80c5d0474d848f20d1d /src/common
parent97607005941e41e60a8025c53f585c7927306fd7 (diff)
downloadhercules-4a07e75620d853ff61c5f29330eae86b2c1cb888.tar.gz
hercules-4a07e75620d853ff61c5f29330eae86b2c1cb888.tar.bz2
hercules-4a07e75620d853ff61c5f29330eae86b2c1cb888.tar.xz
hercules-4a07e75620d853ff61c5f29330eae86b2c1cb888.zip
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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9954 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/common')
-rw-r--r--src/common/socket.c129
-rw-r--r--src/common/socket.h40
2 files changed, 61 insertions, 108 deletions
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