Browse Source

Servers can bind to single IP addresses now, and added buffer.(c/h)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@1033 54d463be-8e91-2dee-dedb-b68131a5f0ec
(no author) 20 years ago
parent
commit
302cc85025
10 changed files with 141 additions and 23 deletions
  1. 4 0
      Changelog.txt
  2. 9 1
      conf-tmpl/login_athena.conf
  3. 10 5
      src/char/char.c
  4. 7 6
      src/char_sql/char.c
  5. 18 0
      src/common/buffer.h
  6. 49 0
      src/common/socket.c
  7. 1 0
      src/common/socket.h
  8. 23 6
      src/login/login.c
  9. 15 2
      src/login_sql/login.c
  10. 5 3
      src/map/clif.c

+ 4 - 0
Changelog.txt

@@ -1,6 +1,10 @@
 Date	Added
 
 02/04
+	* Added common/buffer.(c/h) [SVN 1033: Ajarn]
+	* Login server can now set it's ip address in the config [SVN 1033: Ajarn]
+	* Servers now bind to a single ip address, thus allowing multiple servers to
+	  a single port [SVN 1033: Ajarn]
         * Added experimental code to generate a stack dump when it segfaults, thanks
           to Ser [celest]
           - does not work with Cygwin, as it does not have glibc

+ 9 - 1
conf-tmpl/login_athena.conf

@@ -1,7 +1,15 @@
 // Athena Login Server configuration file.
 // Translated by Peter Kieser <pfak@telus.net>
+
+// Login Server IP
+//
+// You should only need to set this if you are running behind a
+// firewall or on a machine with multiple interfaces.  In that case,
+// you need to specify the IP address you wish to export to the entire world.
+//
+//login_ip:127.0.0.1
  
-// Port to bind Login Server to (always binds to all IP addresses)
+// Login Server Port
 login_port: 6900
 
 // Whether remote administration is enabled or disabled (1 for enabled, 0 for disabled)

+ 10 - 5
src/char/char.c

@@ -49,11 +49,11 @@ char server_name[20];
 char wisp_server_name[24] = "Server";
 int login_ip_set_ = 0;
 char login_ip_str[16];
-int login_ip;
+in_addr_t login_ip;
 int login_port = 6900;
 int char_ip_set_ = 0;
 char char_ip_str[16];
-int char_ip;
+in_addr_t char_ip;
 int char_port = 6121;
 int char_maintenance;
 int char_new;
@@ -769,7 +769,8 @@ void mmo_char_sync(void) {
 	int i, j, k;
 	int lock;
 	FILE *fp,*f_fp;
-	int *id = (int *) aMalloc(sizeof(int) * char_num);
+	//int *id = (int *) aMalloc(sizeof(int) * char_num);
+	CREATE_BUFFER(id, int, char_num);
 
 	// Sorting before save (by [Yor])
 	for(i = 0; i < char_num; i++) {
@@ -808,6 +809,8 @@ void mmo_char_sync(void) {
 		if (fp == NULL) {
 			printf("WARNING: Server can't not create backup of characters file.\n");
 			char_log("WARNING: Server can't not create backup of characters file." RETCODE);
+			//aFree(id); // free up the memory before leaving -.- [Ajarn]
+			DELETE_BUFFER(id);
 			return;
 		}
 		for(i = 0; i < char_num; i++) {
@@ -828,7 +831,8 @@ void mmo_char_sync(void) {
 
 	lock_fclose(f_fp, friends_txt, &lock);
 
-	aFree(id);
+	//aFree(id);
+	DELETE_BUFFER(id);
 
 	return;
 }
@@ -3431,7 +3435,8 @@ int do_init(int argc, char **argv) {
 	set_termfunc(do_final);
 	set_defaultparse(parse_char);
 
-	char_fd = make_listen_port(char_port);
+	//char_fd = make_listen_port(char_port);
+	char_fd = make_listen_bind(char_ip,char_port);
 
 	add_timer_func_list(check_connect_login_server, "check_connect_login_server");
 	add_timer_func_list(send_users_tologin, "send_users_tologin");

+ 7 - 6
src/char_sql/char.c

@@ -89,11 +89,11 @@ char server_name[20];
 char wisp_server_name[24] = "Server";
 int login_ip_set_ = 0;
 char login_ip_str[128];
-int login_ip;
+in_addr_t login_ip;
 int login_port = 6900;
 int char_ip_set_ = 0;
 char char_ip_str[128];
-int char_ip;
+in_addr_t char_ip;
 int char_port = 6121;
 int char_maintenance;
 int char_new;
@@ -3305,16 +3305,13 @@ int do_init(int argc, char **argv){
 	printf("set terminate function -> do_final().....\n");
 	set_termfunc(do_final);
 
-	printf("open port %d.....\n",char_port);
-	char_fd = make_listen_port(char_port);
-
         if ((naddr_ != 0) && (login_ip_set_ == 0 || char_ip_set_ == 0)) {
           // The char server should know what IP address it is running on
           //   - MouseJstr
           int localaddr = ntohl(addr_[0]);
           unsigned char *ptr = (unsigned char *) &localaddr;
           char buf[16];
-          sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);;
+          sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
           if (naddr_ != 1)
             printf("Multiple interfaces detected..  using %s as our IP address\n", buf);
           else
@@ -3331,6 +3328,10 @@ int do_init(int argc, char **argv){
 	login_ip = inet_addr(login_ip_str);
 	char_ip = inet_addr(char_ip_str);
 
+	printf("open port %d.....\n",char_port);
+	//char_fd = make_listen_port(char_port);
+	char_fd = make_listen_bind(char_ip,char_port);
+
 	// send ALIVE PING to login server.
 	printf("add interval tic (check_connect_login_server)....\n");
 	i = add_timer_interval(gettick() + 10, check_connect_login_server, 0, 0, 10 * 1000);

+ 18 - 0
src/common/buffer.h

@@ -0,0 +1,18 @@
+#ifndef _BUFFER_H_
+#define _BUFFER_H_
+
+// Full credit for this goes to Shinomori [Ajarn]
+
+#ifdef __GNUC__ // GCC has variable length arrays
+
+#define CREATE_BUFFER(name, type, size) type name[size]
+#define DELETE_BUFFER(name)
+
+#else // others don't, so we emulate them
+
+#define CREATE_BUFFER(name, type, size) type *name=(type*)aCalloc(size,sizeof(type))
+#define DELETE_BUFFER(name) aFree(name);name=NULL
+
+#endif
+
+#endif

+ 49 - 0
src/common/socket.c

@@ -270,6 +270,55 @@ int make_listen_port(int port)
 	return fd;
 }
 
+int make_listen_bind(long ip,int port)
+{
+	struct sockaddr_in server_address;
+	int fd;
+	int result;
+
+	fd = socket( AF_INET, SOCK_STREAM, 0 );
+	if(fd_max<=fd) fd_max=fd+1;
+
+#ifdef _WIN32
+        {
+	  	unsigned long val = 1;
+  		ioctlsocket(fd, FIONBIO, &val);
+        }
+#else
+	result = fcntl(fd, F_SETFL, O_NONBLOCK);
+#endif
+
+	setsocketopts(fd);
+
+	server_address.sin_family      = AF_INET;
+	server_address.sin_addr.s_addr = ip;
+	server_address.sin_port        = htons((unsigned short)port);
+
+	result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
+	if( result == -1 ) {
+		perror("bind");
+		exit(1);
+	}
+	result = listen( fd, 5 );
+	if( result == -1 ) { /* error */
+		perror("listen");
+		exit(1);
+	}
+
+	FD_SET(fd, &readfds );
+
+	CREATE(session[fd], struct socket_data, 1);
+
+	if(session[fd]==NULL){
+		printf("out of memory : make_listen_bind\n");
+		exit(1);
+	}
+	memset(session[fd],0,sizeof(*session[fd]));
+	session[fd]->func_recv = connect_client;
+
+	return fd;
+}
+
 // Console Reciever [Wizputer]
 int console_recieve(int i) {
 	int n;

+ 1 - 0
src/common/socket.h

@@ -88,6 +88,7 @@ extern int fd_max;
 // Function prototype declaration
 
 int make_listen_port(int);
+int make_listen_bind(long,int);
 int make_connection(long,int);
 int delete_session(int);
 int realloc_fifo(int fd,int rfifo_size,int wfifo_size);

+ 23 - 6
src/login/login.c

@@ -54,6 +54,8 @@ void Gettimeofday(struct timeval *timenow)
 int account_id_count = START_ACCOUNT_NUM;
 int server_num;
 int new_account_flag = 0;
+char login_ip_str[16];
+in_addr_t login_ip;
 int login_port = 6900;
 char lan_char_ip[16];
 int subneti[4];
@@ -872,7 +874,8 @@ void mmo_auth_sync(void) {
 	int i, j, k, lock;
 	int account_id;
 	//int id[auth_num];
-	int *id = (int *)aCalloc(auth_num, sizeof(int));
+	//int *id = (int *)aCalloc(auth_num, sizeof(int));
+	CREATE_BUFFER(id, int, auth_num);
 	char line[65536];
 
 	// Sorting before save
@@ -891,7 +894,8 @@ void mmo_auth_sync(void) {
 
 	// Data save
 	if ((fp = lock_fopen(account_filename, &lock)) == NULL) {
-		if (id) free(id);
+		//if (id) aFree(id); // aFree, right?
+		DELETE_BUFFER(id);
 		return;
 	}
 
@@ -924,7 +928,8 @@ void mmo_auth_sync(void) {
 	if (auth_before_save_file < AUTH_BEFORE_SAVE_FILE)
 		auth_before_save_file = AUTH_BEFORE_SAVE_FILE;
 
-	if (id) aFree(id);
+	//if (id) aFree(id);
+	DELETE_BUFFER(id);
 
 	return;
 }
@@ -1891,7 +1896,8 @@ int parse_admin(int fd) {
 			{
 				int st, ed, len;
 				//int id[auth_num];
-				int *id=(int *)aCalloc(auth_num, sizeof(int));
+				//int *id=(int *)aCalloc(auth_num, sizeof(int));
+				CREATE_BUFFER(id, int, auth_num);
 				st = RFIFOL(fd,2);
 				ed = RFIFOL(fd,6);
 				RFIFOSKIP(fd,10);
@@ -1935,7 +1941,8 @@ int parse_admin(int fd) {
 				}
 				WFIFOW(fd,2) = len;
 				WFIFOSET(fd,len);
-				if (id) free(id);
+				//if (id) free(id);
+				DELETE_BUFFER(id);
 			}
 			break;
 
@@ -3412,6 +3419,14 @@ int login_config_read(const char *cfgName) {
 				level_new_gm = atoi(w2);
 			} else if (strcmpi(w1, "new_account") == 0) {
 				new_account_flag = config_switch(w2);
+			} else if (strcmpi(w1, "login_ip") == 0) {
+				//login_ip_set_ = 1;
+				h = gethostbyname (w2);
+				if (h != NULL) {
+					printf("Login server IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+					sprintf(login_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+				} else
+					memcpy(login_ip_str,w2,16);
 			} else if (strcmpi(w1, "login_port") == 0) {
 				login_port = atoi(w2);
 			} else if (strcmpi(w1, "account_filename") == 0) {
@@ -3938,7 +3953,9 @@ int do_init(int argc, char **argv) {
 	read_gm_account();
 //	set_termfunc(mmo_auth_sync);
 	set_defaultparse(parse_login);
-	login_fd = make_listen_port(login_port);
+	login_ip = inet_addr(login_ip_str);
+	//login_fd = make_listen_port(login_port);
+	login_fd = make_listen_bind(login_ip,login_port);
 
 	if(anti_freeze_enable > 0) {
 		add_timer_func_list(char_anti_freeze_system, "char_anti_freeze_system");

+ 15 - 2
src/login_sql/login.c

@@ -81,6 +81,8 @@ void Gettimeofday(struct timeval *timenow)
 int account_id_count = START_ACCOUNT_NUM;
 int server_num;
 int new_account_flag = 0;
+char login_ip_str[16];
+in_addr_t login_ip;
 int login_port = 6900;
 char lan_char_ip[128]; // Lan char ip added by kashy
 int subnetmaski[4]; // Subnetmask added by kashy
@@ -1591,7 +1593,15 @@ int login_config_read(const char *cfgName){
 		if(i!=2)
 			continue;
 
-		else if(strcmpi(w1,"login_port")==0){
+		} else if (strcmpi(w1, "login_ip") == 0) {
+			//login_ip_set_ = 1;
+			h = gethostbyname (w2);
+			if (h != NULL) {
+				printf("Login server IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+				sprintf(login_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+			} else
+				memcpy(login_ip_str,w2,16);
+		} else if(strcmpi(w1,"login_port")==0){
 			login_port=atoi(w2);
 			printf ("set login_port : %s\n",w2);
 		}
@@ -1804,7 +1814,10 @@ int do_init(int argc,char **argv){
 	printf ("set max servers complete\n");
 	//server port open & binding
 
-	login_fd=make_listen_port(login_port);
+	login_ip = inet_addr(login_ip_str);
+
+	//login_fd=make_listen_port(login_port);
+	login_fd=make_listen_bind(login_ip,login_port);
 
 	//Auth start
 	printf ("Running mmo_auth_sqldb_init()\n");

+ 5 - 3
src/map/clif.c

@@ -10907,7 +10907,7 @@ static int packetdb_readdb(void)
 		{clif_parse_PMIgnoreList,"wisexlist"},
 		{clif_parse_PMIgnoreAll,"wisall"},
 		{clif_parse_friends_list_add,"friendslistadd"},
-		{clif_parse_friends_list_remove,"friendslistremove"},		
+		{clif_parse_friends_list_remove,"friendslistremove"},
 		{clif_parse_GMkillall,"killall"},
 		{clif_parse_GM_Monster_Item,"summon"},
 		{clif_parse_Shift,"shift"},
@@ -11356,13 +11356,15 @@ int do_init_clif(void) {
 
 	set_defaultparse(clif_parse);
 #ifdef __WIN32
-	if (!make_listen_port(map_port)) {
+	//if (!make_listen_port(map_port)) {
+	if (!make_listen_bind(map_ip,map_port)) {
 		printf("cant bind game port\n");
 		exit(1);
 	}
 #else
 	for(i = 0; i < 10; i++) {
-		if (make_listen_port(map_port))
+		//if (make_listen_port(map_port))
+		if (make_listen_bind(map_ip,map_port))
 			break;
 		sleep(20);
 	}