summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-05 18:49:57 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-05 18:49:57 +0000
commit88a5d0cdda513357496b9d53878618e1620f47e8 (patch)
tree4f3c2bedbac4b715ff783de5e1c8d1aefe4395af /src/common
parenta7fd6bfe9bcce1862b554f5841d9ff1aedf473e3 (diff)
downloadhercules-88a5d0cdda513357496b9d53878618e1620f47e8.tar.gz
hercules-88a5d0cdda513357496b9d53878618e1620f47e8.tar.bz2
hercules-88a5d0cdda513357496b9d53878618e1620f47e8.tar.xz
hercules-88a5d0cdda513357496b9d53878618e1620f47e8.zip
* Made a crazy attempt to at least partially synchronize login&char code
* Major edit to the way the servers handle ip addresses, making them obey the "host byte order inside, network byte order outside" rule - hopefully covered all entry- and exit-points for IP address data - discovered several places where Gravity's client breaks the convention, will need to come up with a suitable countermeasure for that - other than that, the code should be portable, except for printing and ipban mask testing (those still assume a specific byte order) - tested both txt and sql in all usual situations; tested single- and multi-server setups, all seems to work (but watch out for hidden bugs!) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10162 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/common')
-rw-r--r--src/common/mmo.h4
-rw-r--r--src/common/socket.c70
-rw-r--r--src/common/socket.h18
-rw-r--r--src/common/strlib.c46
-rw-r--r--src/common/strlib.h17
-rw-r--r--src/common/utils.c46
6 files changed, 94 insertions, 107 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 03c3d7484..f07876115 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -215,8 +215,8 @@ struct mmo_charstatus {
short str,agi,vit,int_,dex,luk;
unsigned char char_num,sex;
- unsigned long mapip;
- unsigned int mapport;
+ uint32 mapip;
+ uint16 mapport;
struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
struct item inventory[MAX_INVENTORY],cart[MAX_CART];
diff --git a/src/common/socket.c b/src/common/socket.c
index f7b5ebc2f..b2c9810b4 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -242,7 +242,7 @@ int connect_client(int listen_fd)
len = sizeof(client_address);
- fd = accept(listen_fd,(struct sockaddr*)&client_address,&len);
+ fd = accept(listen_fd, (struct sockaddr*)&client_address, &len);
if ( fd == INVALID_SOCKET ) {
ShowError("accept failed (code %i)!\n", s_errno);
return -1;
@@ -258,7 +258,7 @@ int connect_client(int listen_fd)
set_nonblocking(fd, 1);
#ifndef MINICORE
- if( ip_rules && !connect_check(*(uint32*)(&client_address.sin_addr)) ){
+ if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) {
do_close(fd);
return -1;
}
@@ -270,13 +270,13 @@ int connect_client(int listen_fd)
fd_max = fd + 1;
create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
- session[fd]->client_addr = client_address;
+ session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
session[fd]->rdata_tick = last_tick;
return fd;
}
-int make_listen_bind(long ip,int port)
+int make_listen_bind(uint32 ip, uint16 port)
{
struct sockaddr_in server_address;
int fd;
@@ -293,8 +293,8 @@ int make_listen_bind(long ip,int port)
set_nonblocking(fd, 1);
server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = ip;
- server_address.sin_port = htons((unsigned short)port);
+ server_address.sin_addr.s_addr = htonl(ip);
+ server_address.sin_port = htons(port);
result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
if( result == SOCKET_ERROR ) {
@@ -320,7 +320,7 @@ int make_listen_bind(long ip,int port)
return fd;
}
-int make_connection(long ip, int port)
+int make_connection(uint32 ip, uint16 port)
{
struct sockaddr_in server_address;
int fd;
@@ -335,12 +335,11 @@ int make_connection(long ip, int port)
setsocketopts(fd);
- server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = ip;
- server_address.sin_port = htons((unsigned short)port);
+ server_address.sin_family = AF_INET;
+ server_address.sin_addr.s_addr = htonl(ip);
+ server_address.sin_port = htons(port);
- ShowStatus("Connecting to %d.%d.%d.%d:%i\n",
- (ip)&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,(ip>>24)&0xFF,port);
+ ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port);
result = connect(fd, (struct sockaddr *)(&server_address), sizeof(struct sockaddr_in));
if( result == SOCKET_ERROR ) {
@@ -389,7 +388,7 @@ int delete_session(int fd)
return 0;
}
-int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size)
+int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
{
if( !session_isValid(fd) )
return 0;
@@ -421,7 +420,7 @@ int realloc_writefifo(int fd, size_t addition)
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;
+ newsize = session[fd]->max_wdata / 2;
else
return 0; //No change
} else if( session[fd]->max_wdata > wfifo_size && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata )
@@ -437,7 +436,7 @@ int realloc_writefifo(int fd, size_t addition)
return 0;
}
-int RFIFOSKIP(int fd,int len)
+int RFIFOSKIP(int fd, int len)
{
struct socket_data *s;
@@ -468,11 +467,10 @@ int WFIFOSET(int fd, int len)
// we have written len bytes to the buffer already before calling WFIFOSET
if(s->wdata_size+len > s->max_wdata)
{ // actually there was a buffer overflow already
- unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
- ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n", fd,
- sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3], len, s->wdata_size, s->max_wdata);
- ShowDebug("Likely command that caused it: 0x%x\n",
- (*(unsigned short*)(s->wdata + s->wdata_size)));
+ uint32 ip = s->client_addr;
+ ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n",
+ fd, CONVIP(ip), len, s->wdata_size, s->max_wdata);
+ ShowDebug("Likely command that caused it: 0x%x\n", (*(unsigned short*)(s->wdata + s->wdata_size)));
// no other chance, make a better fifo model
exit(1);
}
@@ -645,15 +643,13 @@ static int access_order = ACO_DENY_ALLOW;
static int access_allownum = 0;
static int access_denynum = 0;
static int access_debug = 0;
-static int ddos_count = 10;
-static int ddos_interval = 3*1000;
-static int ddos_autoreset = 10*60*1000;
+static int ddos_count = 10;
+static int ddos_interval = 3*1000;
+static int ddos_autoreset = 10*60*1000;
/// Connection history, an array of linked lists.
/// 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)
@@ -816,7 +812,7 @@ int access_ipmask(const char* str, AccessControl* acc)
unsigned int m[4];
int n;
- if( strcmp(str,"all") == 0 ){
+ if( strcmp(str,"all") == 0 ) {
ip = 0;
mask = 0;
} else {
@@ -856,7 +852,7 @@ int access_ipmask(const char* str, AccessControl* acc)
#endif
//////////////////////////////
-int socket_config_read(const char *cfgName)
+int socket_config_read(const char* cfgName)
{
char line[1024],w1[1024],w2[1024];
FILE *fp;
@@ -960,7 +956,7 @@ void do_close(int fd)
/// Retrieve local ips in host byte order.
/// Uses loopback is no address is found.
-int socket_getips(uint32 *ips, int max)
+int socket_getips(uint32* ips, int max)
{
int num = 0;
@@ -986,7 +982,7 @@ int socket_getips(uint32 *ips, int max)
{
hent = gethostbyname(fullhost);
if( hent == NULL ){
- ShowError("socket_getips: Cannot resolve our own hostname to a IP address\n");
+ ShowError("socket_getips: Cannot resolve our own hostname to an IP address\n");
return 0;
}
a = (u_long**)hent->h_addr_list;
@@ -1099,16 +1095,18 @@ int session_isActive(int fd)
return ( session_isValid(fd) && !session[fd]->eof );
}
-
-in_addr_t host2ip(const char* hostname)
+// Resolves hostname into a numeric ip.
+uint32 host2ip(const char* hostname)
{
struct hostent* h = gethostbyname(hostname);
- return (h != NULL) ? *(in_addr_t*)h->h_addr : 0;
+ return (h != NULL) ? ntohl(*(uint32*)h->h_addr) : 0;
}
-const char* ip2str(in_addr_t ip, char ip_str[16])
+// Converts a numeric ip into a dot-formatted string.
+// Result is placed either into a user-provided buffer or a static system buffer.
+const char* ip2str(uint32 ip, char ip_str[16])
{
- in_addr_t addr = ntohl(ip);
- sprintf(ip_str, "%d.%d.%d.%d", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF);
- return ip_str;
+ struct in_addr addr;
+ addr.s_addr = htonl(ip);
+ return (ip_str == NULL) ? inet_ntoa(addr) : strncpy(ip_str, inet_ntoa(addr), 16);
}
diff --git a/src/common/socket.h b/src/common/socket.h
index b7b8ce839..ba984eb3a 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -81,7 +81,7 @@ struct socket_data {
size_t rdata_size, wdata_size;
size_t rdata_pos;
time_t rdata_tick; // time of last receive (for detecting timeouts)
- struct sockaddr_in client_addr; // remote client address (zero for s2s connections)
+ uint32 client_addr; // remote client address (zero for s2s connections)
void* session_data;
RecvFunc func_recv;
SendFunc func_send;
@@ -106,12 +106,12 @@ extern int session_isActive(int fd);
// Function prototype declaration
-int make_listen_bind(long,int);
-int make_connection(long,int);
-int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size);
+int make_listen_bind(uint32 ip, uint16 port);
+int make_connection(uint32 ip, uint16 port);
+int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
int realloc_writefifo(int fd, size_t addition);
-int WFIFOSET(int fd,int len);
-int RFIFOSKIP(int fd,int len);
+int WFIFOSET(int fd, int len);
+int RFIFOSKIP(int fd, int len);
int do_sendrecv(int next);
int do_parsepacket(void);
@@ -126,9 +126,9 @@ extern void set_nonblocking(int fd, int yes);
void set_defaultparse(ParseFunc defaultparse);
// hostname/ip conversion functions
-in_addr_t host2ip(const char* hostname);
-const char* ip2str(in_addr_t ip, char ip_str[16]);
-
+uint32 host2ip(const char* hostname);
+const char* ip2str(uint32 ip, char ip_str[16]);
+#define CONVIP(ip) (ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,(ip>>0)&0xFF
int socket_getips(uint32* ips, int max);
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 9d79e2745..327b2daf1 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -11,12 +11,15 @@
#include "../common/utils.h"
#include "../common/malloc.h"
-//-----------------------------------------------
-// string lib.
-char* jstrescape (char* pt) {
+
+#define J_MAX_MALLOC_SIZE 65535
+
+// escapes a string in-place (' -> \' , \ -> \\ , % -> _)
+char* jstrescape (char* pt)
+{
//copy from here
char *ptr;
- int i =0, j=0;
+ int i = 0, j = 0;
//copy string to temporary
CREATE(ptr, char, J_MAX_MALLOC_SIZE);
@@ -41,10 +44,12 @@ char* jstrescape (char* pt) {
}
pt[j++] = '\0';
aFree(ptr);
- return &pt[0];
+ return pt;
}
-char* jstrescapecpy (char* pt, const char* spt) {
+// escapes a string into a provided buffer
+char* jstrescapecpy (char* pt, const char* spt)
+{
//copy from here
//WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
//a escape character is found, the target's final length increases! [Skotlex]
@@ -75,7 +80,10 @@ char* jstrescapecpy (char* pt, const char* spt) {
pt[j++] = '\0';
return &pt[0];
}
-int jmemescapecpy (char* pt,char* spt, int size) {
+
+// escapes exactly 'size' bytes of a string into a provided buffer
+int jmemescapecpy (char* pt, const char* spt, int size)
+{
//copy from here
int i =0, j=0;
@@ -100,11 +108,9 @@ int jmemescapecpy (char* pt,char* spt, int size) {
return j;
}
-//-----------------------------------------------------
// Function to suppress control characters in a string.
-//-----------------------------------------------------
-//int remove_control_chars(char *str) {
-int remove_control_chars(unsigned char *str) {
+int remove_control_chars(char* str)
+{
int i;
int change = 0;
@@ -119,11 +125,11 @@ int remove_control_chars(unsigned char *str) {
}
//Trims a string, also removes illegal characters such as \t and reduces continous spaces to a single one. by [Foruken]
-char *trim(char *str, const char *delim)
+char* trim(char* str, const char* delim)
{
- char *strp = strtok(str,delim);
+ char* strp = strtok(str,delim);
char buf[1024];
- char *bufp = buf;
+ char* bufp = buf;
memset(buf,0,sizeof buf);
while(strp) {
@@ -143,7 +149,7 @@ char *trim(char *str, const char *delim)
//stristr: Case insensitive version of strstr, code taken from
//http://www.daniweb.com/code/snippet313.html, Dave Sinkula
//
-const char *stristr(const char *haystack, const char *needle)
+const char* stristr(const char* haystack, const char* needle)
{
if ( !*needle )
{
@@ -153,9 +159,7 @@ const char *stristr(const char *haystack, const char *needle)
{
if ( TOUPPER(*haystack) == TOUPPER(*needle) )
{
- /*
- * Matched starting char -- loop through remaining chars.
- */
+ // matched starting char -- loop through remaining chars
const char *h, *n;
for ( h = haystack, n = needle; *h && *n; ++h, ++n )
{
@@ -164,9 +168,9 @@ const char *stristr(const char *haystack, const char *needle)
break;
}
}
- if ( !*n ) /* matched all of 'needle' to null termination */
+ if ( !*n ) // matched all of 'needle' to null termination
{
- return haystack; /* return the start of the match */
+ return haystack; // return the start of the match
}
}
}
@@ -174,7 +178,7 @@ const char *stristr(const char *haystack, const char *needle)
}
#ifdef __WIN32
-char *_strtok_r(char *s1, const char *s2, char **lasts)
+char* _strtok_r(char *s1, const char *s2, char **lasts)
{
char *ret;
diff --git a/src/common/strlib.h b/src/common/strlib.h
index f9a6e41a3..332e823b9 100644
--- a/src/common/strlib.h
+++ b/src/common/strlib.h
@@ -4,25 +4,20 @@
#ifndef _STRLIB_H_
#define _STRLIB_H_
-#define J_MAX_MALLOC_SIZE 65535
-// String function library.
-// code by Jioh L. Jung (ziozzang@4wish.net)
-// This code is under license "BSD"
char* jstrescape (char* pt);
char* jstrescapecpy (char* pt, const char* spt);
-int jmemescapecpy (char* pt,char* spt, int size);
+int jmemescapecpy (char* pt, const char* spt, int size);
+
+int remove_control_chars(char *);
+char *trim(char *str, const char *delim);
+const char *stristr(const char *haystack, const char *needle);
#ifdef __WIN32
#define HAVE_STRTOK_R
#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
-char *_strtok_r(char *s1, const char *s2, char **lasts);
+char* _strtok_r(char* s1, const char* s2, char** lasts);
#endif
-// custom functions
-int remove_control_chars(unsigned char *);
-char *trim(char *str, const char *delim);
-const char *stristr(const char *haystack, const char *needle);
-
#if !defined(WIN32) || (defined(_MSC_VER) && _MSC_VER < 1400)
size_t strnlen (const char* string, size_t maxlen);
#endif
diff --git a/src/common/utils.c b/src/common/utils.c
index c06e57083..2f5cf8705 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -20,28 +20,28 @@
#include "../common/showmsg.h"
#include "../common/cbasetypes.h"
-void dump(unsigned char *buffer, int num)
+void dump(unsigned char* buffer, int num)
{
- int icnt,jcnt;
+ int icnt, jcnt;
printf(" Hex ASCII\n");
printf(" ----------------------------------------------- ----------------");
- for (icnt=0;icnt<num;icnt+=16) {
- printf("\n%p ",&buffer[icnt]);
- for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
+ for (icnt = 0; icnt < num; icnt += 16) {
+ printf("\n%p ", &buffer[icnt]);
+ for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
if (jcnt < num) {
- printf("%02hX ",buffer[jcnt]);
+ printf("%02hX ", buffer[jcnt]);
} else
printf(" ");
}
printf(" | ");
- for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
+ for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
if (jcnt < num) {
if (buffer[jcnt] > 31 && buffer[jcnt] < 127)
- printf("%c",buffer[jcnt]);
+ printf("%c", buffer[jcnt]);
else
printf(".");
} else
@@ -266,30 +266,20 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
unsigned char GetByte(unsigned long val, size_t num)
{
- switch(num)
- {
- case 0:
- return (unsigned char)((val & 0x000000FF) );
- case 1:
- return (unsigned char)((val & 0x0000FF00)>>0x08);
- case 2:
- return (unsigned char)((val & 0x00FF0000)>>0x10);
- case 3:
- return (unsigned char)((val & 0xFF000000)>>0x18);
- default:
- return 0; //better throw something here
+ switch(num) {
+ case 0: return (unsigned char)((val & 0x000000FF) );
+ case 1: return (unsigned char)((val & 0x0000FF00)>>0x08);
+ case 2: return (unsigned char)((val & 0x00FF0000)>>0x10);
+ case 3: return (unsigned char)((val & 0xFF000000)>>0x18);
+ default: return 0; //better throw something here
}
}
unsigned short GetWord(unsigned long val, size_t num)
{
- switch(num)
- {
- case 0:
- return (unsigned short)((val & 0x0000FFFF) );
- case 1:
- return (unsigned short)((val & 0xFFFF0000)>>0x10);
- default:
- return 0; //better throw something here
+ switch(num) {
+ case 0: return (unsigned short)((val & 0x0000FFFF) );
+ case 1: return (unsigned short)((val & 0xFFFF0000)>>0x10);
+ default: return 0; //better throw something here
}
}
unsigned short MakeWord(unsigned char byte0, unsigned char byte1)