summaryrefslogtreecommitdiff
path: root/src/common/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/socket.c')
-rw-r--r--src/common/socket.c129
1 files changed, 42 insertions, 87 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);