summaryrefslogtreecommitdiff
path: root/src/common/socket.c
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/socket.c
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/socket.c')
-rw-r--r--src/common/socket.c70
1 files changed, 34 insertions, 36 deletions
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);
}