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.c269
1 files changed, 174 insertions, 95 deletions
diff --git a/src/common/socket.c b/src/common/socket.c
index d4b8bb43f..95d8bf578 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2016 Hercules Dev Team
+ * Copyright (C) 2012-2018 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/nullpo.h"
+#include "common/packets.h"
#include "common/showmsg.h"
#include "common/strlib.h"
#include "common/timer.h"
@@ -75,19 +76,17 @@
/**
* Socket Interface Source
**/
-struct socket_interface sockt_s;
+static struct socket_interface sockt_s;
struct socket_interface *sockt;
-struct socket_data **session;
-
-const char *SOCKET_CONF_FILENAME = "conf/common/socket.conf";
+static const char *SOCKET_CONF_FILENAME = "conf/common/socket.conf";
#ifdef SEND_SHORTLIST
// Add a fd to the shortlist so that it'll be recognized as a fd that needs
// sending done on it.
-void send_shortlist_add_fd(int fd);
+static void send_shortlist_add_fd(int fd);
// Do pending network sends (and eof handling) from the shortlist.
-void send_shortlist_do_sends(void);
+static void send_shortlist_do_sends(void);
#endif // SEND_SHORTLIST
/////////////////////////////////////////////////////////////////////
@@ -123,7 +122,7 @@ static int sock_arr_len = 0;
///
/// @param s Socket
/// @return Fd or -1
-int sock2fd(SOCKET s)
+static int sock2fd(SOCKET s)
{
int fd;
@@ -144,7 +143,7 @@ int sock2fd(SOCKET s)
///
/// @param s Socket
/// @return New fd or -1
-int sock2newfd(SOCKET s)
+static int sock2newfd(SOCKET s)
{
int fd;
@@ -164,7 +163,7 @@ int sock2newfd(SOCKET s)
return fd;
}
-int sAccept(int fd, struct sockaddr* addr, int* addrlen)
+static int sAccept(int fd, struct sockaddr *addr, int *addrlen)
{
SOCKET s;
@@ -175,14 +174,14 @@ int sAccept(int fd, struct sockaddr* addr, int* addrlen)
return sock2newfd(s);
}
-int sClose(int fd)
+static int sClose(int fd)
{
int ret = closesocket(fd2sock(fd));
fd2sock(fd) = INVALID_SOCKET;
return ret;
}
-int sSocket(int af, int type, int protocol)
+static int sSocket(int af, int type, int protocol)
{
SOCKET s;
@@ -193,7 +192,7 @@ int sSocket(int af, int type, int protocol)
return sock2newfd(s);
}
-char* sErr(int code)
+static char *sErr(int code)
{
static char sbuf[512];
// strerror does not handle socket codes
@@ -259,7 +258,7 @@ char* sErr(int code)
#ifndef SOCKET_EPOLL
// Select based Event Dispatcher:
-fd_set readfds;
+static fd_set readfds;
#else // SOCKET_EPOLL
// Epoll based Event Dispatcher:
@@ -296,19 +295,17 @@ static time_t socket_data_last_tick = 0;
#define WFIFO_MAX (1*1024*1024)
#ifdef SEND_SHORTLIST
-int send_shortlist_array[FD_SETSIZE];// we only support FD_SETSIZE sockets, limit the array to that
-int send_shortlist_count = 0;// how many fd's are in the shortlist
-uint32 send_shortlist_set[(FD_SETSIZE+31)/32];// to know if specific fd's are already in the shortlist
+static int send_shortlist_array[FD_SETSIZE];// we only support FD_SETSIZE sockets, limit the array to that
+static int send_shortlist_count = 0;// how many fd's are in the shortlist
+static uint32 send_shortlist_set[(FD_SETSIZE+31)/32];// to know if specific fd's are already in the shortlist
#endif // SEND_SHORTLIST
static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse);
-#ifndef MINICORE
- int ip_rules = 1;
- static int connect_check(uint32 ip);
-#endif // MINICORE
+static int ip_rules = 1;
+static int connect_check(uint32 ip);
-const char* error_msg(void)
+static const char *error_msg(void)
{
static char buf[512];
int code = sErrno;
@@ -319,13 +316,24 @@ const char* error_msg(void)
/*======================================
* CORE : Default processing functions
*--------------------------------------*/
-int null_recv(int fd) { return 0; }
-int null_send(int fd) { return 0; }
-int null_parse(int fd) { return 0; }
+static int null_recv(int fd)
+{
+ return 0;
+}
-ParseFunc default_func_parse = null_parse;
+static int null_send(int fd)
+{
+ return 0;
+}
-void set_defaultparse(ParseFunc defaultparse)
+static int null_parse(int fd)
+{
+ return 0;
+}
+
+static ParseFunc default_func_parse = null_parse;
+
+static void set_defaultparse(ParseFunc defaultparse)
{
default_func_parse = defaultparse;
}
@@ -333,7 +341,7 @@ void set_defaultparse(ParseFunc defaultparse)
/*======================================
* CORE : Socket options
*--------------------------------------*/
-void set_nonblocking(int fd, unsigned long yes)
+static void set_nonblocking(int fd, unsigned long yes)
{
// FIONBIO Use with a nonzero argp parameter to enable the nonblocking mode of socket s.
// The argp parameter is zero if nonblocking is to be disabled.
@@ -347,7 +355,7 @@ void set_nonblocking(int fd, unsigned long yes)
* @param fd The socket descriptor
* @param opt Optional, additional options to set (Can be NULL).
*/
-void setsocketopts(int fd, struct hSockOpt *opt)
+static void setsocketopts(int fd, struct hSockOpt *opt)
{
#if defined(WIN32)
BOOL yes = TRUE;
@@ -409,7 +417,7 @@ void setsocketopts(int fd, struct hSockOpt *opt)
/*======================================
* CORE : Socket Sub Function
*--------------------------------------*/
-void set_eof(int fd)
+static void set_eof(int fd)
{
if (sockt->session_is_active(fd)) {
#ifdef SEND_SHORTLIST
@@ -420,7 +428,7 @@ void set_eof(int fd)
}
}
-int recv_to_fifo(int fd)
+static int recv_to_fifo(int fd)
{
ssize_t len;
@@ -457,7 +465,7 @@ int recv_to_fifo(int fd)
return 0;
}
-int send_from_fifo(int fd)
+static int send_from_fifo(int fd)
{
ssize_t len;
@@ -504,13 +512,13 @@ int send_from_fifo(int fd)
}
/// Best effort - there's no warranty that the data will be sent.
-void flush_fifo(int fd)
+static void flush_fifo(int fd)
{
if(sockt->session[fd] != NULL)
sockt->session[fd]->func_send(fd);
}
-void flush_fifos(void)
+static void flush_fifos(void)
{
int i;
for(i = 1; i < sockt->fd_max; i++)
@@ -520,7 +528,7 @@ void flush_fifos(void)
/*======================================
* CORE : Connection functions
*--------------------------------------*/
-int connect_client(int listen_fd)
+static int connect_client(int listen_fd)
{
int fd;
struct sockaddr_in client_address;
@@ -547,12 +555,10 @@ int connect_client(int listen_fd)
setsocketopts(fd,NULL);
sockt->set_nonblocking(fd, 1);
-#ifndef MINICORE
if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) {
sockt->close(fd);
return -1;
}
-#endif // MINICORE
#ifndef SOCKET_EPOLL
// Select Based Event Dispatcher
@@ -575,11 +581,12 @@ int connect_client(int listen_fd)
create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
sockt->session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
+ sockt->session[fd]->flag.validate = sockt->validate;
return fd;
}
-int make_listen_bind(uint32 ip, uint16 port)
+static int make_listen_bind(uint32 ip, uint16 port)
{
struct sockaddr_in server_address = { 0 };
int fd;
@@ -644,11 +651,10 @@ int make_listen_bind(uint32 ip, uint16 port)
create_session(fd, connect_client, null_send, null_parse);
sockt->session[fd]->client_addr = 0; // just listens
sockt->session[fd]->rdata_tick = 0; // disable timeouts on this socket
-
return fd;
}
-int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt)
+static int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt)
{
struct sockaddr_in remote_address = { 0 };
int fd;
@@ -749,7 +755,7 @@ static void delete_session(int fd)
}
}
-int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
+static int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
{
if (!sockt->session_is_valid(fd))
return 0;
@@ -766,7 +772,7 @@ int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
return 0;
}
-int realloc_writefifo(int fd, size_t addition)
+static int realloc_writefifo(int fd, size_t addition)
{
size_t newsize;
@@ -794,7 +800,7 @@ int realloc_writefifo(int fd, size_t addition)
}
/// advance the RFIFO cursor (marking 'len' bytes as processed)
-int rfifoskip(int fd, size_t len)
+static int rfifoskip(int fd, size_t len)
{
struct socket_data *s;
@@ -805,7 +811,36 @@ int rfifoskip(int fd, size_t len)
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);
+ Assert_report(0);
len = RFIFOREST(fd);
+ } else {
+ const size_t lenRest = RFIFOREST(fd);
+ if (s->flag.validate == 1 && len == lenRest) {
+ if (lenRest >= 2) {
+ const uint32 cmd = (uint32)RFIFOW(fd, 0);
+ if (cmd < MIN_PACKET_DB || cmd > MAX_PACKET_DB) {
+ ShowError("Skip wrong packet id: 0x%04X\n", cmd);
+ Assert_report(0);
+ } else {
+ int packet_len = packets->db[cmd];
+ if (packet_len == -1) {
+ if (lenRest < 4) {
+ ShowError("Skip packet with size smaller than 4\n");
+ Assert_report(0);
+ } else {
+ packet_len = RFIFOW(fd, 2);
+ if (packet_len != lenRest) {
+ ShowError("Skip packet 0x%04X with dynamic size %"PRIuS", but must be size %d\n", cmd, lenRest, packet_len);
+ Assert_report(0);
+ }
+ }
+ } else if (packet_len != lenRest) {
+ ShowError("Skip packet 0x%04X with size %"PRIuS", but must be size %d\n", cmd, lenRest, packet_len);
+ Assert_report(0);
+ }
+ }
+ }
+ }
}
s->rdata_pos = s->rdata_pos + len;
@@ -816,14 +851,12 @@ int rfifoskip(int fd, size_t len)
}
/// advance the WFIFO cursor (marking 'len' bytes for sending)
-int wfifoset(int fd, size_t len)
+static int wfifoset(int fd, size_t len, bool validate)
{
- size_t newreserve;
- struct socket_data* s;
-
if (!sockt->session_is_valid(fd))
return 0;
- s = sockt->session[fd];
+
+ struct socket_data* s = sockt->session[fd];
if (s == NULL || s->wdata == NULL)
return 0;
@@ -862,6 +895,10 @@ int wfifoset(int fd, size_t len)
}
}
+
+ if (validate && s->flag.validate == 1)
+ sockt->validateWfifo(fd, len);
+
s->wdata_size += len;
#ifdef SHOW_SERVER_STATS
socket_data_qo += len;
@@ -872,7 +909,7 @@ int wfifoset(int fd, size_t len)
// always keep a WFIFO_SIZE reserve in the buffer
// For inter-server connections, let the reserve be 1/4th of the link size.
- newreserve = s->flag.server ? FIFOSIZE_SERVERLINK / 4 : WFIFO_SIZE;
+ size_t newreserve = s->flag.server ? FIFOSIZE_SERVERLINK / 4 : WFIFO_SIZE;
// readjust the buffer to include the chosen reserve
sockt->realloc_writefifo(fd, newreserve);
@@ -884,7 +921,16 @@ int wfifoset(int fd, size_t len)
return 0;
}
-int do_sockets(int next)
+static void wfifohead(int fd, size_t len)
+{
+ Assert_retv(fd >= 0);
+
+ sockt->session[fd]->last_head_size = (uint32)len;
+ if (sockt->session[fd]->wdata_size + len > sockt->session[fd]->max_wdata)
+ sockt->realloc_writefifo(fd, len);
+}
+
+static int do_sockets(int next)
{
#ifndef SOCKET_EPOLL
fd_set rfd;
@@ -1056,9 +1102,6 @@ int do_sockets(int next)
return 0;
}
-//////////////////////////////
-#ifndef MINICORE
-//////////////////////////////
// IP rules and DDoS protection
struct connect_history {
@@ -1088,7 +1131,7 @@ static int access_debug = 0;
static int ddos_count = 10;
static int ddos_interval = 3*1000;
static int ddos_autoreset = 10*60*1000;
-struct DBMap *connect_history = NULL;
+static struct DBMap *connect_history = NULL;
static int connect_check_(uint32 ip);
@@ -1232,7 +1275,7 @@ static int connect_check_clear(int tid, int64 tick, int id, intptr_t data)
/// Parses the ip address and mask and puts it into acc.
/// Returns 1 is successful, 0 otherwise.
-int access_ipmask(const char *str, struct access_control *acc)
+static int access_ipmask(const char *str, struct access_control *acc)
{
uint32 ip;
uint32 mask;
@@ -1288,7 +1331,7 @@ int access_ipmask(const char *str, struct access_control *acc)
*
* @retval false in case of failure
*/
-bool access_list_add(struct config_setting_t *setting, const char *list_name, struct access_control_list *access_list)
+static bool access_list_add(struct config_setting_t *setting, const char *list_name, struct access_control_list *access_list)
{
const char *temp = NULL;
int i, setting_length;
@@ -1317,10 +1360,6 @@ bool access_list_add(struct config_setting_t *setting, const char *list_name, st
return true;
}
-//////////////////////////////
-#endif // MINICORE
-//////////////////////////////
-
/**
* Reads 'socket_configuration/ip_rules' and initializes required variables.
*
@@ -1330,9 +1369,8 @@ bool access_list_add(struct config_setting_t *setting, const char *list_name, st
*
* @retval false in case of error.
*/
-bool socket_config_read_iprules(const char *filename, struct config_t *config, bool imported)
+static bool socket_config_read_iprules(const char *filename, struct config_t *config, bool imported)
{
-#ifndef MINICORE
struct config_setting_t *setting = NULL;
const char *temp = NULL;
@@ -1375,7 +1413,6 @@ bool socket_config_read_iprules(const char *filename, struct config_t *config, b
} else {
access_list_add(setting, "deny_list", &access_deny);
}
-#endif // ! MINICORE
return true;
}
@@ -1389,9 +1426,8 @@ bool socket_config_read_iprules(const char *filename, struct config_t *config, b
*
* @retval false in case of error.
*/
-bool socket_config_read_ddos(const char *filename, struct config_t *config, bool imported)
+static bool socket_config_read_ddos(const char *filename, struct config_t *config, bool imported)
{
-#ifndef MINICORE
struct config_setting_t *setting = NULL;
nullpo_retr(false, filename);
@@ -1408,7 +1444,6 @@ bool socket_config_read_ddos(const char *filename, struct config_t *config, bool
libconfig->setting_lookup_int(setting, "count", &ddos_count);
libconfig->setting_lookup_int(setting, "autoreset", &ddos_autoreset);
-#endif // ! MINICORE
return true;
}
@@ -1420,7 +1455,7 @@ bool socket_config_read_ddos(const char *filename, struct config_t *config, bool
*
* @retval false in case of error.
*/
-bool socket_config_read(const char *filename, bool imported)
+static bool socket_config_read(const char *filename, bool imported)
{
struct config_t config;
struct config_setting_t *setting = NULL;
@@ -1455,7 +1490,6 @@ bool socket_config_read(const char *filename, bool imported)
}
#endif // SOCKET_EPOLL
-#ifndef MINICORE
{
uint32 ui32 = 0;
libconfig->setting_lookup_bool(setting, "debug", &access_debug);
@@ -1468,7 +1502,6 @@ bool socket_config_read(const char *filename, bool imported)
retval = false;
if (!socket_config_read_ddos(filename, &config, imported))
retval = false;
-#endif // MINICORE
// import should overwrite any previous configuration, so it should be called last
if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
@@ -1484,15 +1517,13 @@ bool socket_config_read(const char *filename, bool imported)
return retval;
}
-void socket_final(void)
+static void socket_final(void)
{
int i;
-#ifndef MINICORE
if( connect_history )
db_destroy(connect_history);
VECTOR_CLEAR(access_allow);
VECTOR_CLEAR(access_deny);
-#endif // MINICORE
for( i = 1; i < sockt->fd_max; i++ )
if(sockt->session[i])
@@ -1523,7 +1554,7 @@ void socket_final(void)
}
/// Closes a socket.
-void socket_close(int fd)
+static void socket_close(int fd)
{
if( fd <= 0 ||fd >= FD_SETSIZE )
return;// invalid
@@ -1537,7 +1568,7 @@ void socket_close(int fd)
// Epoll based Event Dispatcher
epevent.data.fd = fd;
epevent.events = EPOLLIN;
- epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &epevent); // removing the socket from epoll when it's being closed is not required but recommended
+ epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &epevent); // removing the socket from epoll when it's being closed is not required but recommended
#endif // SOCKET_EPOLL
sShutdown(fd, SHUT_RDWR); // Disallow further reads/writes
@@ -1547,7 +1578,7 @@ void socket_close(int fd)
/// Retrieve local ips in host byte order.
/// Uses loopback is no address is found.
-int socket_getips(uint32* ips, int max)
+static int socket_getips(uint32 *ips, int max)
{
int num = 0;
@@ -1628,7 +1659,7 @@ int socket_getips(uint32* ips, int max)
return num;
}
-void socket_init(void)
+static void socket_init(void)
{
uint64 rlim_cur = FD_SETSIZE;
@@ -1677,10 +1708,8 @@ void socket_init(void)
}
#endif // defined(HAVE_SETRLIMIT) && !defined(CYGWIN)
-#ifndef MINICORE
VECTOR_INIT(access_allow);
VECTOR_INIT(access_deny);
-#endif // ! MINICORE
// Get initial local ips
sockt->naddr_ = sockt->getips(sockt->addr_,16);
@@ -1694,7 +1723,7 @@ void socket_init(void)
#else // SOCKET_EPOLL
// Epoll based Event Dispatcher:
- epfd = epoll_create(FD_SETSIZE); // 2.6.8 or newer ignores the expected socket amount argument
+ epfd = epoll_create(FD_SETSIZE); // 2.6.8 or newer ignores the expected socket amount argument
if(epfd == SOCKET_ERROR){
ShowError("Failed to Create Epoll Event Dispatcher: %s\n", error_msg());
exit(EXIT_FAILURE);
@@ -1720,28 +1749,26 @@ void socket_init(void)
// 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);
-#ifndef MINICORE
// Delete old connection history every 5 minutes
connect_history = uidb_alloc(DB_OPT_RELEASE_DATA);
timer->add_func_list(connect_check_clear, "connect_check_clear");
timer->add_interval(timer->gettick()+1000, connect_check_clear, 0, 0, 5*60*1000);
-#endif // MINICORE
ShowInfo("Server supports up to '"CL_WHITE"%"PRIu64""CL_RESET"' concurrent connections.\n", rlim_cur);
}
-bool session_is_valid(int fd)
+static bool session_is_valid(int fd)
{
return ( fd > 0 && fd < FD_SETSIZE && sockt->session[fd] != NULL );
}
-bool session_is_active(int fd)
+static bool session_is_active(int fd)
{
return ( sockt->session_is_valid(fd) && !sockt->session[fd]->flag.eof );
}
// Resolves hostname into a numeric ip.
-uint32 host2ip(const char *hostname)
+static uint32 host2ip(const char *hostname)
{
struct hostent* h;
nullpo_ret(hostname);
@@ -1757,7 +1784,7 @@ uint32 host2ip(const char *hostname)
*
* @return A pointer to the output string.
*/
-const char *ip2str(uint32 ip, char *ip_str)
+static const char *ip2str(uint32 ip, char *ip_str)
{
struct in_addr addr;
addr.s_addr = htonl(ip);
@@ -1765,20 +1792,20 @@ const char *ip2str(uint32 ip, char *ip_str)
}
// Converts a dot-formatted ip string into a numeric ip.
-uint32 str2ip(const char* ip_str)
+static uint32 str2ip(const char *ip_str)
{
return ntohl(inet_addr(ip_str));
}
// Reorders bytes from network to little endian (Windows).
// Necessary for sending port numbers to the RO client until Gravity notices that they forgot ntohs() calls.
-uint16 ntows(uint16 netshort)
+static uint16 ntows(uint16 netshort)
{
return ((netshort & 0xFF) << 8) | ((netshort & 0xFF00) >> 8);
}
/* [Ind/Hercules] - socket_datasync */
-void socket_datasync(int fd, bool send)
+static void socket_datasync(int fd, bool send)
{
struct {
unsigned int length;/* short is not enough for some */
@@ -1809,6 +1836,11 @@ void socket_datasync(int fd, bool send)
{ sizeof(struct guild_castle) },
{ sizeof(struct fame_list) },
{ PACKETVER },
+ { PACKETVER_MAIN_NUM },
+ { PACKETVER_RE_NUM },
+ { PACKETVER_ZERO_NUM },
+ { PACKETVER_AD_NUM },
+ { PACKETVER_SAK_NUM },
};
unsigned short i;
unsigned int alen = ARRAYLENGTH(data_list);
@@ -1845,7 +1877,7 @@ void socket_datasync(int fd, bool send)
#ifdef SEND_SHORTLIST
// Add a fd to the shortlist so that it'll be recognized as a fd that needs
// sending or eof handling.
-void send_shortlist_add_fd(int fd)
+static void send_shortlist_add_fd(int fd)
{
int i;
int bit;
@@ -1872,7 +1904,7 @@ void send_shortlist_add_fd(int fd)
}
// Do pending network sends and eof handling from the shortlist.
-void send_shortlist_do_sends(void)
+static void send_shortlist_do_sends(void)
{
int i;
@@ -1928,7 +1960,7 @@ void send_shortlist_do_sends(void)
* @retval 0 if it is a WAN IP.
* @return the appropriate LAN server address to send, if it is a LAN IP.
*/
-uint32 socket_lan_subnet_check(uint32 ip, struct s_subnet *info)
+static uint32 socket_lan_subnet_check(uint32 ip, struct s_subnet *info)
{
int i;
ARR_FIND(0, VECTOR_LENGTH(sockt->lan_subnets), i, SUBNET_MATCH(ip, VECTOR_INDEX(sockt->lan_subnets, i).ip, VECTOR_INDEX(sockt->lan_subnets, i).mask));
@@ -1952,7 +1984,7 @@ uint32 socket_lan_subnet_check(uint32 ip, struct s_subnet *info)
* @retval true if we allow server connections from the given IP.
* @retval false otherwise.
*/
-bool socket_allowed_ip_check(uint32 ip)
+static bool socket_allowed_ip_check(uint32 ip)
{
int i;
ARR_FIND(0, VECTOR_LENGTH(sockt->allowed_ips), i, SUBNET_MATCH(ip, VECTOR_INDEX(sockt->allowed_ips, i).ip, VECTOR_INDEX(sockt->allowed_ips, i).mask));
@@ -1968,7 +2000,7 @@ bool socket_allowed_ip_check(uint32 ip)
* @retval true if we trust the given IP.
* @retval false otherwise.
*/
-bool socket_trusted_ip_check(uint32 ip)
+static bool socket_trusted_ip_check(uint32 ip)
{
int i;
ARR_FIND(0, VECTOR_LENGTH(sockt->trusted_ips), i, SUBNET_MATCH(ip, VECTOR_INDEX(sockt->trusted_ips, i).ip, VECTOR_INDEX(sockt->trusted_ips, i).mask));
@@ -1988,7 +2020,7 @@ bool socket_trusted_ip_check(uint32 ip)
* @param[in] groupname Current group name, for output/logging reasons.
* @return The amount of entries read, zero in case of errors.
*/
-int socket_net_config_read_sub(struct config_setting_t *t, struct s_subnet_vector *list, const char *filename, const char *groupname)
+static int socket_net_config_read_sub(struct config_setting_t *t, struct s_subnet_vector *list, const char *filename, const char *groupname)
{
int i, len;
char ipbuf[64], maskbuf[64];
@@ -2022,7 +2054,7 @@ int socket_net_config_read_sub(struct config_setting_t *t, struct s_subnet_vecto
*
* @param filename The filename to read from.
*/
-void socket_net_config_read(const char *filename)
+static void socket_net_config_read(const char *filename)
{
struct config_t network_config;
int i;
@@ -2063,6 +2095,50 @@ void socket_net_config_read(const char *filename)
return;
}
+static void socket_validateWfifo(int fd, size_t len)
+{
+ if (len < 2) {
+ ShowError("Sent packet with size smaller than 2\n");
+ Assert_retv(0);
+ return;
+ }
+ const uint32 cmd = (uint32)WFIFOW(fd, 0);
+ const uint32 last_head_size = sockt->session[fd]->last_head_size;
+ sockt->session[fd]->last_head_size = 0;
+
+ if (cmd < MIN_PACKET_DB || cmd > MAX_PACKET_DB) {
+ ShowError("Sent wrong packet id: 0x%04X\n", cmd);
+ Assert_retv(0);
+ return;
+ }
+ if (len > 65535) {
+ ShowError("Sent packet with size bigger than 65535\n");
+ Assert_retv(0);
+ return;
+ }
+ int packet_len = packets->db[cmd];
+ const int len2 = (int)len;
+ if (packet_len == -1) {
+ if (len2 < 4) {
+ ShowError("Sent packet with size smaller than 4\n");
+ Assert_retv(0);
+ return;
+ }
+ packet_len = WFIFOW(fd, 2);
+ if (packet_len != len2) {
+ ShowError("Sent packet 0x%04X with dynamic size %d, but must be size %d\n", cmd, len2, packet_len);
+ Assert_retv(0);
+ }
+ } else if (packet_len != len2) {
+ ShowError("Sent packet 0x%04X with size %d, but must be size %d\n", cmd, len2, packet_len);
+ Assert_retv(0);
+ }
+ if (last_head_size < (uint32)packet_len) {
+ ShowError("Reserved too small packet buffer for packet 0x%04X with size %u, but must be size %d\n", cmd, last_head_size, packet_len);
+ Assert_retv(0);
+ }
+}
+
void socket_defaults(void)
{
sockt = &sockt_s;
@@ -2074,6 +2150,7 @@ void socket_defaults(void)
/* */
memset(&sockt->addr_, 0, sizeof(sockt->addr_));
sockt->naddr_ = 0;
+ sockt->validate = false;
/* */
VECTOR_INIT(sockt->lan_subnets);
VECTOR_INIT(sockt->allowed_ips);
@@ -2091,6 +2168,7 @@ void socket_defaults(void)
sockt->realloc_fifo = realloc_fifo;
sockt->realloc_writefifo = realloc_writefifo;
sockt->wfifoset = wfifoset;
+ sockt->wfifohead = wfifohead;
sockt->rfifoskip = rfifoskip;
sockt->close = socket_close;
/* */
@@ -2113,4 +2191,5 @@ void socket_defaults(void)
sockt->trusted_ip_check = socket_trusted_ip_check;
sockt->net_config_read_sub = socket_net_config_read_sub;
sockt->net_config_read = socket_net_config_read;
+ sockt->validateWfifo = socket_validateWfifo;
}