int get_local_hostname ( std::string& hostname ) { // ensure that WSAStartup has been called and WSACleanup will eventually // be called when program ends sockets_startup(); try { char temp[NI_MAXHOST]; if (gethostname(temp,NI_MAXHOST) == SOCKET_ERROR ) { return OTHER_ERROR; } hostname = temp; } catch (...) { return OTHER_ERROR; } return 0; }
int hostname_to_ip ( const std::string& hostname, std::string& ip, int n ) { // ensure that WSAStartup has been called and WSACleanup will eventually // be called when program ends sockets_startup(); try { // lock this mutex since gethostbyname isn't really thread safe auto_mutex M(sockets_kernel_1_mutex::startup_lock); // if no hostname was given then return error if ( hostname.empty()) return OTHER_ERROR; hostent* address; address = gethostbyname(hostname.c_str()); if (address == 0) { return OTHER_ERROR; } // find the nth address in_addr* addr = reinterpret_cast<in_addr*>(address->h_addr_list[0]); for (int i = 1; i <= n; ++i) { addr = reinterpret_cast<in_addr*>(address->h_addr_list[i]); // if there is no nth address then return error if (addr == 0) return OTHER_ERROR; } char* resolved_ip = inet_ntoa(*addr); // check if inet_ntoa returned an error if (resolved_ip == NULL) { return OTHER_ERROR; } ip.assign(resolved_ip); } catch(...) { return OTHER_ERROR; } return 0; }
int ip_to_hostname ( const std::string& ip, std::string& hostname ) { // ensure that WSAStartup has been called and WSACleanup will eventually // be called when program ends sockets_startup(); try { // lock this mutex since gethostbyaddr isn't really thread safe auto_mutex M(sockets_kernel_1_mutex::startup_lock); // if no ip was given then return error if (ip.empty()) return OTHER_ERROR; hostent* address; unsigned long ipnum = inet_addr(ip.c_str()); // if inet_addr couldn't convert ip then return an error if (ipnum == INADDR_NONE) { return OTHER_ERROR; } address = gethostbyaddr(reinterpret_cast<char*>(&ipnum),4,AF_INET); // check if gethostbyaddr returned an error if (address == 0) { return OTHER_ERROR; } hostname.assign(address->h_name); } catch (...) { return OTHER_ERROR; } return 0; }
int create_connection ( connection*& new_connection, unsigned short foreign_port, const std::string& foreign_ip, unsigned short local_port, const std::string& local_ip ) { sockets_startup(); sockaddr_in local_sa; // local socket structure sockaddr_in foreign_sa; // foreign socket structure memset(&local_sa,'\0',sizeof(sockaddr_in)); // initialize local_sa memset(&foreign_sa,'\0',sizeof(sockaddr_in)); // initialize foreign_sa dsocklen_t length; int sock = socket (AF_INET, SOCK_STREAM, 0); // get a new socket // if socket() returned an error then return OTHER_ERROR if (sock == -1 ) { return OTHER_ERROR; } // set the foreign socket structure foreign_sa.sin_family = AF_INET; foreign_sa.sin_port = htons(foreign_port); foreign_sa.sin_addr.s_addr = inet_addr(foreign_ip.c_str()); // if inet_addr couldn't convert the ip then return an error if ( foreign_sa.sin_addr.s_addr == ( in_addr_t)(-1)) { close_socket(sock); return OTHER_ERROR; } // set up the local socket structure local_sa.sin_family = AF_INET; // set the local port local_sa.sin_port = htons(local_port); // set the local ip if (local_ip.empty()) { // if the listener should listen on any IP local_sa.sin_addr.s_addr = htons(INADDR_ANY); } else { // if there is a specific ip to listen on local_sa.sin_addr.s_addr = inet_addr(local_ip.c_str()); // if inet_addr couldn't convert the ip then return an error if ( local_sa.sin_addr.s_addr == ( in_addr_t)(-1)) { close_socket(sock); return OTHER_ERROR; } } // bind the new socket to the requested local port and local ip if ( bind(sock,reinterpret_cast<sockaddr*>(&local_sa),sizeof(sockaddr_in)) == -1) { // if there was an error close_socket(sock); // if the port is already bound then return PORTINUSE if (errno == EADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // connect the socket if ( connect ( sock, reinterpret_cast<sockaddr*>(&foreign_sa), sizeof(sockaddr_in) ) == -1 ) { close_socket(sock); // if the port is already bound then return PORTINUSE if (errno == EADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // determine the local port and IP and store them in used_local_ip // and used_local_port int used_local_port; char temp_used_local_ip[16]; std::string used_local_ip; sockaddr_in local_info; // determine the port if (local_port == 0) { length = sizeof(sockaddr_in); if ( getsockname( sock, reinterpret_cast<sockaddr*>(&local_info), &length ) == -1) { close_socket(sock); return OTHER_ERROR; } used_local_port = ntohs(local_info.sin_port); } else { used_local_port = local_port; } // determine the ip if (local_ip.empty()) { // if local_port is not 0 then we must fill the local_info structure if (local_port != 0) { length = sizeof(sockaddr_in); if ( getsockname ( sock, reinterpret_cast<sockaddr*>(&local_info), &length ) == -1 ) { close_socket(sock); return OTHER_ERROR; } } used_local_ip = inet_ntop(AF_INET,&local_info.sin_addr,temp_used_local_ip,16); } else { used_local_ip = local_ip; } // set the SO_OOBINLINE option int flag_value = 1; if (setsockopt(sock,SOL_SOCKET,SO_OOBINLINE,reinterpret_cast<const void*>(&flag_value),sizeof(int))) { close_socket(sock); return OTHER_ERROR; } // initialize a connection object on the heap with the new socket try { new_connection = new connection ( sock, foreign_port, foreign_ip, used_local_port, used_local_ip ); } catch(...) {close_socket(sock); return OTHER_ERROR; } return 0; }
int create_listener ( listener*& new_listener, unsigned short port, const std::string& ip ) { sockets_startup(); sockaddr_in sa; // local socket structure memset(&sa,'\0',sizeof(sockaddr_in)); // initialize sa int sock = socket (AF_INET, SOCK_STREAM, 0); // get a new socket // if socket() returned an error then return OTHER_ERROR if (sock == -1) { return OTHER_ERROR; } // set the local socket structure sa.sin_family = AF_INET; sa.sin_port = htons(port); if (ip.empty()) { // if the listener should listen on any IP sa.sin_addr.s_addr = htons(INADDR_ANY); } else { // if there is a specific ip to listen on sa.sin_addr.s_addr = inet_addr(ip.c_str()); // if inet_addr couldn't convert the ip then return an error if ( sa.sin_addr.s_addr == ( in_addr_t)(-1)) { close_socket(sock); return OTHER_ERROR; } } // set the SO_REUSEADDR option int flag_value = 1; if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,reinterpret_cast<const void*>(&flag_value),sizeof(int))) { close_socket(sock); return OTHER_ERROR; } // bind the new socket to the requested port and ip if (bind(sock,reinterpret_cast<sockaddr*>(&sa),sizeof(sockaddr_in)) == -1) { // if there was an error close_socket(sock); // if the port is already bound then return PORTINUSE if (errno == EADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // tell the new socket to listen if ( listen(sock,SOMAXCONN) == -1) { // if there was an error return OTHER_ERROR close_socket(sock); // if the port is already bound then return PORTINUSE if (errno == EADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // determine the used local port if necessary if (port == 0) { sockaddr_in local_info; dsocklen_t length = sizeof(sockaddr_in); if ( getsockname( sock, reinterpret_cast<sockaddr*>(&local_info), &length ) == -1) { close_socket(sock); return OTHER_ERROR; } port = ntohs(local_info.sin_port); } // initialize a listener object on the heap with the new socket try { new_listener = new listener(sock,port,ip); } catch(...) { close_socket(sock); return OTHER_ERROR; } return 0; }
int create_connection ( connection*& new_connection, unsigned short foreign_port, const std::string& foreign_ip, unsigned short local_port, const std::string& local_ip ) { // ensure that WSAStartup has been called and WSACleanup // will eventually be called when program ends sockets_startup(); sockaddr_in local_sa; // local socket structure sockaddr_in foreign_sa; // foreign socket structure ZeroMemory(&local_sa,sizeof(sockaddr_in)); // initialize local_sa ZeroMemory(&foreign_sa,sizeof(sockaddr_in)); // initialize foreign_sa int length; SOCKET sock = socket (AF_INET, SOCK_STREAM, 0); // get a new socket // if socket() returned an error then return OTHER_ERROR if (sock == INVALID_SOCKET ) { return OTHER_ERROR; } // set the foreign socket structure foreign_sa.sin_family = AF_INET; foreign_sa.sin_port = htons(foreign_port); foreign_sa.sin_addr.S_un.S_addr = inet_addr(foreign_ip.c_str()); // if inet_addr couldn't convert the ip then return an error if ( foreign_sa.sin_addr.S_un.S_addr == INADDR_NONE ) { closesocket(sock); return OTHER_ERROR; } // set up the local socket structure local_sa.sin_family = AF_INET; // set the local ip if (local_ip.empty()) { // if the listener should listen on any IP local_sa.sin_addr.S_un.S_addr = htons(INADDR_ANY); } else { // if there is a specific ip to listen on local_sa.sin_addr.S_un.S_addr = inet_addr(local_ip.c_str()); // if inet_addr couldn't convert the ip then return an error if (local_sa.sin_addr.S_un.S_addr == INADDR_NONE) { closesocket(sock); return OTHER_ERROR; } } // set the local port local_sa.sin_port = htons(local_port); // bind the new socket to the requested local port and local ip if ( bind ( sock, reinterpret_cast<sockaddr*>(&local_sa), sizeof(sockaddr_in) ) == SOCKET_ERROR ) { const int err = WSAGetLastError(); // if there was an error closesocket(sock); // if the port is already bound then return PORTINUSE if (err == WSAEADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // connect the socket if (connect ( sock, reinterpret_cast<sockaddr*>(&foreign_sa), sizeof(sockaddr_in) ) == SOCKET_ERROR ) { const int err = WSAGetLastError(); closesocket(sock); // if the port is already bound then return PORTINUSE if (err == WSAEADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // determine the local port and IP and store them in used_local_ip // and used_local_port int used_local_port; std::string used_local_ip; sockaddr_in local_info; if (local_port == 0) { length = sizeof(sockaddr_in); if (getsockname ( sock, reinterpret_cast<sockaddr*>(&local_info), &length ) == SOCKET_ERROR ) { closesocket(sock); return OTHER_ERROR; } used_local_port = ntohs(local_info.sin_port); } else { used_local_port = local_port; } // determine real local ip if (local_ip.empty()) { // if local_port is not 0 then we must fill the local_info structure if (local_port != 0) { length = sizeof(sockaddr_in); if ( getsockname ( sock, reinterpret_cast<sockaddr*>(&local_info), &length ) == SOCKET_ERROR ) { closesocket(sock); return OTHER_ERROR; } } char* temp = inet_ntoa(local_info.sin_addr); // check if inet_ntoa returned an error if (temp == NULL) { closesocket(sock); return OTHER_ERROR; } used_local_ip.assign(temp); } else { used_local_ip = local_ip; } // set the SO_OOBINLINE option int flag_value = 1; if (setsockopt(sock,SOL_SOCKET,SO_OOBINLINE,reinterpret_cast<const char*>(&flag_value),sizeof(int)) == SOCKET_ERROR ) { closesocket(sock); return OTHER_ERROR; } // initialize a connection object on the heap with the new socket try { new_connection = new connection ( sock, foreign_port, foreign_ip, used_local_port, used_local_ip ); } catch(...) {closesocket(sock); return OTHER_ERROR; } return 0; }
int create_listener ( listener*& new_listener, unsigned short port, const std::string& ip ) { // ensure that WSAStartup has been called and WSACleanup will eventually // be called when program ends sockets_startup(); sockaddr_in sa; // local socket structure ZeroMemory(&sa,sizeof(sockaddr_in)); // initialize sa SOCKET sock = socket (AF_INET, SOCK_STREAM, 0); // get a new socket // if socket() returned an error then return OTHER_ERROR if (sock == INVALID_SOCKET ) { return OTHER_ERROR; } // set the local socket structure sa.sin_family = AF_INET; sa.sin_port = htons(port); if (ip.empty()) { // if the listener should listen on any IP sa.sin_addr.S_un.S_addr = htons(INADDR_ANY); } else { // if there is a specific ip to listen on sa.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); // if inet_addr couldn't convert the ip then return an error if ( sa.sin_addr.S_un.S_addr == INADDR_NONE ) { closesocket(sock); return OTHER_ERROR; } } // set the SO_REUSEADDR option int flag_value = 1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,reinterpret_cast<const char*>(&flag_value),sizeof(int)); // bind the new socket to the requested port and ip if (bind(sock,reinterpret_cast<sockaddr*>(&sa),sizeof(sockaddr_in))==SOCKET_ERROR) { const int err = WSAGetLastError(); // if there was an error closesocket(sock); // if the port is already bound then return PORTINUSE if (err == WSAEADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // tell the new socket to listen if ( listen(sock,SOMAXCONN) == SOCKET_ERROR) { const int err = WSAGetLastError(); // if there was an error return OTHER_ERROR closesocket(sock); // if the port is already bound then return PORTINUSE if (err == WSAEADDRINUSE) return PORTINUSE; else return OTHER_ERROR; } // determine the port used if necessary if (port == 0) { sockaddr_in local_info; int length = sizeof(sockaddr_in); if ( getsockname ( sock, reinterpret_cast<sockaddr*>(&local_info), &length ) == SOCKET_ERROR ) { closesocket(sock); return OTHER_ERROR; } port = ntohs(local_info.sin_port); } // initialize a listener object on the heap with the new socket try { new_listener = new listener(sock,port,ip); } catch(...) { closesocket(sock); return OTHER_ERROR; } return 0; }