? .deps ? Makefile ? Makefile.in ? config.h ? crack-attack ? out.diff ? stamp-h1 ? gtk-gui/.deps ? gtk-gui/Makefile ? gtk-gui/Makefile.in Index: Attack.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Attack.cxx,v retrieving revision 1.15 diff -u -r1.15 Attack.cxx --- Attack.cxx 13 May 2005 19:00:02 -0000 1.15 +++ Attack.cxx 16 May 2005 19:44:06 -0000 @@ -27,6 +27,7 @@ #include #include #include +#include #ifndef _WIN32 # include @@ -54,8 +55,6 @@ #include "gtk-gui/gui_main.h" #endif -#define GC_HOST_NAME_SIZE (256) - /* * Documentation * html tables don't work right in explorer @@ -77,12 +76,15 @@ if (argc <= 1) return gui_main(argc, argv); #endif char player_name[GC_PLAYER_NAME_LENGTH]; - char host_name[GC_HOST_NAME_SIZE]; - int port; + char host_name[NI_MAXHOST]; + char port[NI_MAXSERV]; int mode = 0; int height = -1, width = -1; player_name[0] = '\0'; + host_name[0] = '\0'; + port[0] = '\0'; + parseCommandLine(argc, argv, mode, port, host_name, player_name, height, width); run_crack_attack(mode, port, host_name, player_name, height, width); @@ -91,8 +93,8 @@ inline void usage ( ) { - cerr << "Usage: " GC_BINARY " --server [PORT] [--low] [--extreme] [--wait] " - "[--name 'NAME']\n" + cerr << "Usage: " GC_BINARY " --server [PORT] [--bind ADDRESS] [--wait] [--extreme] " + "[[--really] --low] [--name 'NAME']\n" " \n" " " GC_BINARY " SERVER PORT [[--really] --low] [--name 'NAME']\n" " \n" @@ -109,7 +111,7 @@ void run_crack_attack ( int mode, - int port, + char *port, char *host_name, char *player_name, int width, @@ -159,7 +161,7 @@ #endif } -void parseCommandLine ( int argc, char **argv, int &mode, int &port, +void parseCommandLine ( int argc, char **argv, int &mode, char *port, char *host_name, char *player_name , int &height, int &width ) { for (int n = 1; argv[n]; n++) { @@ -172,10 +174,19 @@ mode |= CM_SERVER; if (argv[n + 1] && argv[n + 1][0] != '-') - port = atoi(argv[++n]); + strncpy(port, argv[++n], NI_MAXSERV); else - port = 0; + strncpy(port, "0", NI_MAXSERV); + } else if (!strcmp(argv[n], "--bind")) { + if (!(mode & CM_SERVER)) usage(); + + else if (argv[n + 1] && argv[n + 1][0] != '-') + { + strncpy(host_name, argv[++n], NI_MAXHOST); + cerr << "Binding server to: " << host_name << endl; + } + } else if (!strcmp(argv[n], "-1") || !strcmp(argv[n], "--solo")) { if (mode & (CM_SERVER | CM_CLIENT | CM_SOLO)) usage(); @@ -227,12 +238,12 @@ if (mode & (CM_SERVER | CM_CLIENT | CM_SOLO)) usage(); mode |= CM_CLIENT; - strncpy(host_name, argv[n], GC_HOST_NAME_SIZE); + strncpy(host_name, argv[n], NI_MAXHOST); ++n; if (n < argc) { - port = atoi(argv[n]); + strncpy(port, argv[n], NI_MAXSERV); } else { - port = 0; + strncpy(port, "0", NI_MAXSERV); cerr << "No port specified.\n"; usage(); } Index: Attack.h =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Attack.h,v retrieving revision 1.3 diff -u -r1.3 Attack.h --- Attack.h 16 Apr 2005 13:38:02 -0000 1.3 +++ Attack.h 16 May 2005 19:44:06 -0000 @@ -31,9 +31,9 @@ using namespace std; -void run_crack_attack (int mode, int port, char *host_name, char *player_name, int width, int height); +void run_crack_attack (int mode, char *port, char *host_name, char *player_name, int width, int height); void usage ( ); -void parseCommandLine ( int argc, char **argv, int &mode, int &port, +void parseCommandLine ( int argc, char **argv, int &mode, char *port, char *host_name, char player_name[GC_PLAYER_NAME_LENGTH], int &height, int &width); void setupLocalDataDirectory ( ); Index: Communicator.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Communicator.cxx,v retrieving revision 1.5 diff -u -r1.5 Communicator.cxx --- Communicator.cxx 16 Apr 2005 08:13:38 -0000 1.5 +++ Communicator.cxx 16 May 2005 19:44:09 -0000 @@ -106,7 +106,7 @@ } } -void Communicator::initialize ( int mode, int port, char host_name[256], +void Communicator::initialize ( int mode, char *port, char *host_name, char player_name[GC_PLAYER_NAME_LENGTH] ) { comm_link_active = false; @@ -120,28 +120,81 @@ } #endif - if (port == 0) - port = CO_DEFAULT_PORT; + if (port[0] == '\0') + strncpy(port, CO_DEFAULT_PORT, NI_MAXSERV); switch (mode & (CM_SERVER | CM_CLIENT)) { case CM_SERVER: { - int connection_socket = socket(AF_INET, SOCK_STREAM, 0); + struct addrinfo hints, *res, *ressave; + struct sockaddr_storage address; - sockaddr_in address; + int error, ReUseAddr = 1; + int connection_socket = -1; + + /* Clear the hints variable */ + memset(&hints, 0, sizeof(hints)); + + /* + * AI_PASSIVE flag: the resulting address is used to bind + * to a socket for accepting incoming connections. + * So, when the hostname==NULL, getaddrinfo function will + * return one entry per allowed protocol family containing + * the unspecified address for that family. + */ + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if(host_name[0] == '\0') + error = getaddrinfo(NULL, port, &hints, &res); + else + error = getaddrinfo(host_name, port, &hints, &res); + + if (error != 0) + { + /* handle getaddrinfo error */ + cerr << "Error in getaddrinfo(). host_name: " << host_name << endl; + exit(1); + } + + ressave=res; + + /* + * Try open socket with each address getaddrinfo returned, + * until getting a valid listening socket. + */ + while (res) + { + /* create socket */ + connection_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (connection_socket >= 0) + { #ifndef _WIN32 - int val = 1; - setsockopt (connection_socket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (int)); + /* allow it to always reuse the same port */ + ReUseAddr = 1; + setsockopt(connection_socket, SOL_SOCKET, + SO_REUSEADDR, &ReUseAddr, sizeof(ReUseAddr)); #endif - address.sin_family = AF_INET; - address.sin_addr.s_addr = htonl(INADDR_ANY); - address.sin_port = htons(port); - if (bind(connection_socket, (sockaddr *) &address, sizeof(address)) < 0) { - cerr << "Port " << port << " is busy." << endl; - exit(1); + if (bind(connection_socket, res->ai_addr, res->ai_addrlen) == 0) + break; + + cerr << "Port " << port << " is busy." << endl; + exit(1); + + close(connection_socket); + connection_socket=-1; + } + res = res->ai_next; } - cout << "Waiting for connection at port " << port << "..." << endl; + getnameinfo(res->ai_addr, res->ai_addrlen, + host_name, NI_MAXHOST, port, NI_MAXSERV, + NI_NUMERICHOST | NI_NUMERICSERV); + + freeaddrinfo(ressave); + + cout << "Waiting for connection on " << host_name << " at port " << port << "..." << endl; listen(connection_socket, 1); #ifndef _WIN32 @@ -162,7 +215,15 @@ #else int length = sizeof(address); #endif - comm_link = accept(connection_socket, (sockaddr *) &address, &length); + /* take care: accept is a "slow" system call */ +accept_again: + if ((comm_link = accept(connection_socket, (struct sockaddr *) &address, &length)) < 0) + { + if (errno == EINTR) + goto accept_again; + else + cerr << "Error in accept()" << endl; + } comm_link_active = true; // check version id @@ -186,32 +247,68 @@ // available symmetry breaking term win_ties = true; - cout << "Connection made by " << inet_ntoa(address.sin_addr) << '.' << endl; + char clientname[NI_MAXHOST]; + memset(clientname, 0, sizeof(clientname)); + + getnameinfo((struct sockaddr *)&address, length, + clientname, sizeof(clientname), + port, sizeof(port), + NI_NUMERICHOST); + + cout << "Connection made by " << clientname << '.' << endl; break; } case CM_CLIENT: { - comm_link = socket(AF_INET, SOCK_STREAM, 0); - comm_link_active = true; + struct addrinfo hints, *res, *ressave; + struct sockaddr_storage address; -#ifdef DEVELOPMENT - cout << "Hostname: " << host_name << endl; -#endif - hostent *host = gethostbyname(host_name); - if (!host) { - cerr << "Host '" << host_name << "' not found." << endl; - exit(1); - } + int error; + + cerr << "Port: " << port << endl; - sockaddr_in address; - address.sin_family = AF_INET; - address.sin_addr = *(struct in_addr *) host->h_addr; - address.sin_port = htons((short) port); - if (connect(comm_link, (sockaddr *) &address, sizeof(address)) < 0) { - cerr << "Connection failed. Unable to connect to address." << endl; + /* Clear the hints variable */ + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + cerr << host_name << endl; + + error = getaddrinfo(host_name, port, &hints, &res); + if (error != 0) + { + /* handle getaddrinfo error */ + cerr << "Error in getaddrinfo()." << endl; + perror(gai_strerror(error)); exit(1); } + cerr << "Connecting to " << host_name << endl; + + /* + * Try open socket with each address getaddrinfo returned, + * until getting a valid connection on the socket. + */ + ressave=res; + while (res) + { + /* create socket */ + comm_link = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (comm_link >= 0) + { + + if (connect(comm_link, res->ai_addr, res->ai_addrlen) == 0) + break; + + cerr << "Connection failed. Unable to connect to address." << endl; + close(comm_link); + comm_link=-1; + } + res = res->ai_next; + } + freeaddrinfo(ressave); + // check version id uint32 version_id = CO_TEST_INT; for (char *c = CO_VERSION; *c; c++) @@ -238,8 +335,8 @@ // for simplicity, client loses ties - but don't tell anyone win_ties = false; - cout << "Connection made to " << inet_ntoa(address.sin_addr) << ':' - << (short) port << '.' << endl; + cout << "Connection made to " << host_name << ':' + << port << '.' << endl; break; } } Index: Communicator.h =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Communicator.h,v retrieving revision 1.6 diff -u -r1.6 Communicator.h --- Communicator.h 13 May 2005 17:31:40 -0000 1.6 +++ Communicator.h 16 May 2005 19:44:09 -0000 @@ -41,7 +41,7 @@ #include "Game.h" // default communication port -#define CO_DEFAULT_PORT (8080) +#define CO_DEFAULT_PORT "8080" // seconds before server time out due to no connection #define CO_SERVER_TIME_OUT (30) @@ -77,7 +77,7 @@ /* static */ class Communicator { public: - static void initialize ( int mode, int port, char host_name[256], + static void initialize ( int mode, char *port, char *host_name, char player_name[GC_PLAYER_NAME_LENGTH] ); static void gameStart ( ); static void gameFinish ( ); Index: gtk-gui/interface.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/gtk-gui/interface.cxx,v retrieving revision 1.13 diff -u -r1.13 interface.cxx --- gtk-gui/interface.cxx 2 May 2005 21:03:47 -0000 1.13 +++ gtk-gui/interface.cxx 16 May 2005 19:44:09 -0000 @@ -225,7 +225,7 @@ gtk_widget_show (lblTmpServerAddress); gtk_box_pack_start (GTK_BOX (vbox7), lblTmpServerAddress, FALSE, FALSE, 0); - lblServerAddress = gtk_label_new ("127.0.0.1"); + lblServerAddress = gtk_label_new ("::1"); gtk_widget_set_name (lblServerAddress, "lblServerAddress"); gtk_widget_show (lblServerAddress); gtk_box_pack_start (GTK_BOX (vbox7), lblServerAddress, FALSE, FALSE, 0);