#include "Networking/sockets.h" #include "Networking/ServerSocket.h" #include "Networking/Server.h" #include "Processor/OnlineOptions.h" #include #include #include /* * Get the client ip number on the socket connection for client i. */ void Server::get_ip(int num) { struct sockaddr_storage addr; socklen_t len = sizeof addr; getpeername(socket_num[num], (struct sockaddr*)&addr, &len); // supports both IPv4 and IPv6: char ipstr[INET6_ADDRSTRLEN]; if (addr.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&addr; inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); } else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); } names[num] = ipstr; if (OnlineOptions::singleton.has_option("debug_networking")) cerr << "IP address of party " << num << ": " << names[num] << endl; } void Server::get_name(int num) { if (OnlineOptions::singleton.has_option("debug_networking")) cerr << "Player " << num << " started." << endl; // Receive name sent by client (legacy) - not used here octetStream os; os.Receive(socket_num[num]); receive(socket_num[num],(octet*)&ports[num],4); if (OnlineOptions::singleton.has_option("debug_networking")) cerr << "Player " << num << " listening on " << os.str() << ":" << ports[num] << endl; // Get client IP get_ip(num); } void Server::send_names() { /* Now send the machine names back to each client * and the number of machines */ RunningTimer timer; octetStream addresses; addresses.store(names); addresses.store(ports); for (int i=0; istart(); return 0; } Server* Server::start_networking(Names& N, int my_num, int nplayers, string hostname, int portnum, int my_port) { if (OnlineOptions::singleton.has_option("debug_networking")) cerr << "Starting networking for " << my_num << "/" << nplayers << " with server on " << hostname << ":" << (portnum) << endl; if (my_num < 0 or my_num >= nplayers) { cerr << "Player number " << my_num << " outside range: 0-" << nplayers - 1 << endl; exit(1); } Server* server = 0; pthread_t thread; if (my_num == 0) { pthread_create(&thread, 0, Server::start_in_thread, server = new Server(nplayers, portnum)); bool default_port = my_port == Names::DEFAULT_PORT or my_port == portnum; N.init(my_num, portnum, my_port, hostname.c_str(), not default_port); pthread_join(thread, 0); if (default_port) N.set_server(server->get_socket()); delete server; } else N.init(my_num, portnum, my_port, hostname.c_str()); return 0; } ServerSocket* Server::get_socket() { auto res = server_socket; server_socket = 0; return res; }