TcpConnection* TcpConnector::connect(const TcpSockAddr& addr, int &ret, long timeout) { int sockfd; ret = -1; sockfd = socket(addr.ai_family, SOCK_STREAM, 0); if (sockfd < 0) return 0L; if (timeout < 0) ret = ::connect(sockfd, (struct sockaddr*)&addr.ai_addr, addr.ai_addrlen); else ret = timeout_connect(sockfd, (struct sockaddr*)&addr.ai_addr, addr.ai_addrlen, timeout); if (ret < 0) { close(sockfd); return 0L; } else { TcpConnection *tcon; tcon = new TcpConnection; if (tcon->set_fd(sockfd) < 0) { delete tcon; return 0L; } else { return tcon; } } }
TcpConnection* TcpConnector::connect(const Address& addr, int& ret, long timeout) { int sockfd; struct addrinfo *res; res = addr.addr; ret = -1; if (res == NULL) return 0L; do { sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) continue; if (timeout < 0) { if ((ret=::connect(sockfd, res->ai_addr, res->ai_addrlen)) == 0) break; } else { if ((ret=timeout_connect(sockfd, res->ai_addr, res->ai_addrlen, timeout)) == 0) break; } close(sockfd); } while ((res = res->ai_next) != NULL); if (res) { TcpConnection *tcon; tcon = new TcpConnection; if (tcon->set_fd(sockfd) < 0) { delete tcon; return 0L; } else { return tcon; } } else { return 0L; } }
/* * remote_connect() * Returns a socket connected to a remote host. Properly binds to a local * port or source address if needed. Returns -1 on failure. */ int SoundIP::remote_connect(const char *host, const char *port, struct addrinfo hints) { struct addrinfo *res, *res0; int s, x, ret; if ( getaddrinfo(host, port, &hints, &res) ) return -1; res0 = res; do { if ((s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol)) < 0) continue; if (portmode_udp) { x = 1; ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); if (ret > -1) if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0) break; } else { if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) break; } close(s); s = -1; } while ((res0 = res0->ai_next) != NULL); freeaddrinfo(res); return (s); }
void run_menu() { int rv, i; struct timeval tv; // Start timeout right away so updates will be sent tv.tv_sec = 0; tv.tv_usec = 10; while (1) { // Check for dropped connections for (i = 0; i < MAX_SERVERS; ++i) { if (connect_out[i].in_use == 0) continue; if (difftime(time(NULL), connect_out[i].last_time) > (update_int * 3)) if (connect_out[i].time_out == 0) timeout_connect(i); } // Reset the file descriptor set fds_reset(); rv = select(highsock, &fdread, NULL, NULL, &tv); if (rv < 0) die ("select failed"); // Timeout occured, send updates and reset else if (rv == 0) { send_packet_to_neighbors(); // Reset timer (centiseconds) tv.tv_sec = update_int; tv.tv_usec = 0; continue; } // Input detected from stdin, run the menu if (FD_ISSET(fileno(stdin), &fdread)) { process_menu_input(); continue; } // Input detected on socket if (FD_ISSET(connect_in.fd, &fdread)) { // Read packet, update routing table, and display read_packet(); update_route(); } } }
int main( int argc, char* argv[] ) { if( argc <= 2 ) { printf( "usage: %s ip_address port_number\n", basename( argv[0] ) ); return 1; } const char* ip = argv[1]; int port = atoi( argv[2] ); int sockfd = timeout_connect( ip, port, 10 ); if ( sockfd < 0 ) { return 1; } return 0; }
int make_tcp_connection_from_port(const char * hostname, unsigned short port, unsigned short sport, int mstimeout, int nodelay) { struct sockaddr_in local; int s; int err; int zero = 0; s = socket(AF_INET,SOCK_STREAM,0); if(s<0){ perror("make_tcp_connection: socket"); exit(1); // bad socket } if(nodelay && (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &zero, sizeof(zero)) < 0)) { perror("setsockopt"); fprintf(stderr,"make_tcp_connection::Unable to disable Nagle's algorithm\n"); exit(1); } local.sin_family=PF_INET; local.sin_addr.s_addr=INADDR_ANY; local.sin_port=htons(sport); err=bind(s,(struct sockaddr *)&local, sizeof(local)); if(err) { perror("make_tcp_connection_from_port::bind"); return -4; } err = timeout_connect(s,hostname,port, mstimeout); if(err) { perror("make_tcp_connection: connect"); close(s); return err; // bad connect } return s; }
int sock_open(const char *host, int clientPort, int timeout) { int sock = -1; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { write_log("create sock failed"); return -1; } unsigned long inaddr; struct sockaddr_in ad; memset(&ad, 0, sizeof(ad)); ad.sin_family = AF_INET; ad.sin_port = htons(clientPort); if (inet_aton(host, &ad.sin_addr)) { if (timeout_connect(sock, (struct sockaddr *) &ad, sizeof(ad), timeout) < 0) { close(sock); write_log("host [%s:%d] is unreachable", host, clientPort); return -1; } } else { struct hostent *hp = gethostbyname((char*)host); if (hp == NULL) { close(sock); write_log("get host by name [%s] failed", host); return -1; } if(hp->h_length != 4 && hp->h_length != 8) { close(sock); write_log("get host by name [%s] failed", host); return -1; } struct sockaddr_in **pptr = (struct sockaddr_in **)hp->h_addr_list; for(; *pptr != NULL; pptr++) { memcpy(&ad.sin_addr, *pptr, sizeof(struct in_addr)); if (timeout_connect(sock, (struct sockaddr *) &ad, sizeof(ad), timeout) == 0) { break; } } if(*pptr == NULL) { close(sock); write_log("get host by name [%s] failed", host); return -1; } } return(sock); }
/* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. * If port is 0, the default port will be used. If needpriv is true, * a privileged port will be allocated to make the connection. * This requires super-user privileges if needpriv is true. * Connection_attempts specifies the maximum number of tries (one per * second). If proxy_command is non-NULL, it specifies the command (with %h * and %p substituted for host and port, respectively) to use to contact * the daemon. */ static int ssh_connect_direct(const char *host, struct addrinfo *aitop, struct sockaddr_storage *hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) { int on = 1; int sock = -1, attempt; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo *ai; #ifdef WIN32_FIXME DWORD error_win32 = 0; #endif debug2("ssh_connect: needpriv %d", needpriv); for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ sleep(1); debug("Trying again..."); } /* * Loop through addresses for this host, and try each one in * sequence until the connection succeeds. */ for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("ssh_connect: getnameinfo failed"); continue; } debug("Connecting to %.200s [%.100s] port %s.", host, ntop, strport); /* Create a socket for connecting. */ sock = ssh_create_socket(needpriv, ai); if (sock < 0) /* Any error is already output */ continue; if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, timeout_ms) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; } else { debug("connect to address %s port %s: %s", ntop, strport, strerror(errno)); #ifdef WIN32_FIXME error_win32 = WSAGetLastError(); #endif close(sock); sock = -1; } } if (sock != -1) break; /* Successful connection. */ } /* Return failure if we didn't get a successful connection. */ if (sock == -1) { #ifdef WIN32_FIXME WSASetLastError(error_win32); #endif error("ssh: connect to host %s port %s: %s", host, strport, strerror(errno)); return (-1); } debug("Connection established."); /* Set SO_KEEPALIVE if requested. */ if (want_keepalive && setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); /* Set the connection. */ packet_set_connection(sock, sock); return 0; }
/* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. * If port is 0, the default port will be used. If needpriv is true, * a privileged port will be allocated to make the connection. * This requires super-user privileges if needpriv is true. * Connection_attempts specifies the maximum number of tries (one per * second). If proxy_command is non-NULL, it specifies the command (with %h * and %p substituted for host and port, respectively) to use to contact * the daemon. */ struct ssh * ssh_connect(const char *host, struct sockaddr_storage * hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv, const char *proxy_command) { struct ssh *ssh; int gaierr; int on = 1; int sock = -1, attempt; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo hints, *ai, *aitop; debug2("ssh_connect: needpriv %d", needpriv); /* If a proxy command is given, connect using it. */ if (proxy_command != NULL) return ssh_proxy_connect(host, port, proxy_command); /* No proxy command. */ memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%u", port); if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) fatal("%s: Could not resolve hostname %.100s: %s", __progname, host, ssh_gai_strerror(gaierr)); for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ sleep(1); debug("Trying again..."); } /* * Loop through addresses for this host, and try each one in * sequence until the connection succeeds. */ for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("ssh_connect: getnameinfo failed"); continue; } debug("Connecting to %.200s [%.100s] port %s.", host, ntop, strport); /* Create a socket for connecting. */ sock = ssh_create_socket(needpriv, ai); if (sock < 0) /* Any error is already output */ continue; if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, timeout_ms) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; } else { debug("connect to address %s port %s: %s", ntop, strport, strerror(errno)); close(sock); sock = -1; } } if (sock != -1) break; /* Successful connection. */ } freeaddrinfo(aitop); /* Return failure if we didn't get a successful connection. */ if (sock == -1) { error("ssh: connect to host %s port %s: %s", host, strport, strerror(errno)); return (NULL); } debug("Connection established."); /* Set SO_KEEPALIVE if requested. */ if (want_keepalive && setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); /* Set the connection. */ ssh = ssh_packet_set_connection(NULL, sock, sock); ssh_packet_set_timeout(ssh, options.server_alive_interval, options.server_alive_count_max); return (ssh); }
/** * Same as eConnect() except you may the specify address family here (default is * AF_UNSPEC). * We couldn't just add the new family arg to eConnect because the original one * is pure virtual declared in EClientSocketBase. Thanks C++ design crap ... */ bool EPosixClientSocket::eConnect2( const char *host, unsigned int port, int clientId, int family ) { // already connected? if( m_fd >= 0) { assert(false); // for now we don't allow that return true; } // initialize Winsock DLL (only for Windows) if ( !SocketsInit()) { // Does this set errno? getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), "Initializing Winsock DLL failed."); return false; } // use local machine if no host passed in if ( !( host && *host)) { host = "127.0.0.1"; } // starting to connect to server struct addrinfo *aitop; int s = resolveHost( host, port, family, &aitop ); if( s != 0 ) { SocketsDestroy(); const char *err; #ifdef HAVE_GETADDRINFO err = gai_strerror(s); #else err = "Invalid address, hostname resolving not supported."; #endif getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } int con_errno = 0; for( struct addrinfo *ai = aitop; ai != NULL; ai = ai->ai_next ) { // create socket m_fd = socket(ai->ai_family, ai->ai_socktype, 0); if( m_fd < 0) { con_errno = errno; continue; } /* Set socket O_NONBLOCK. If wanted we could handle errors (portability!) We could even make O_NONBLOCK optional. */ int sn = set_socket_nonblock( m_fd ); assert( sn == 0 ); // try to connect if( timeout_connect( m_fd, ai->ai_addr, ai->ai_addrlen ) < 0 ) { con_errno = errno; SocketClose(m_fd); m_fd = -1; continue; } /* successfully connected */ break; } freeaddrinfo(aitop); /* connection failed, tell the error which happened in our last try */ if( m_fd < 0 ) { const char *err = strerror(con_errno); SocketsDestroy(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } // set client id setClientId( clientId); errno = 0; onConnectBase(); if( !isOutBufferEmpty() ) { /* For now we consider it as error if it's not possible to send an integer string within a single tcp packet. Here we don't know weather ::send() really failed or not. If so then we hopefully still have it's errno set.*/ const char *err = (errno != 0) ? strerror(errno) : "Sending client id failed."; eDisconnect(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } if( wait_socket( m_fd, WAIT_READ ) <= 0 ) { const char *err = (errno != 0) ? strerror(errno) : strerror(ENODATA); eDisconnect(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } while( !isConnected() ) { assert( isSocketOK() ); // need to be handled if send() would destroy it if ( !checkMessagesConnect()) { const char *err = (errno != 0) ? strerror(errno) : "The remote host closed the connection."; eDisconnect(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } } // successfully connected return true; }
/* make connection to server */ int netdial(int domain, int proto, char *local, int local_port, char *server, int port, int timeout) { struct addrinfo hints, *local_res, *server_res; int s, saved_errno; if (local) { memset(&hints, 0, sizeof(hints)); hints.ai_family = domain; hints.ai_socktype = proto; if (getaddrinfo(local, NULL, &hints, &local_res) != 0) return -1; } memset(&hints, 0, sizeof(hints)); hints.ai_family = domain; hints.ai_socktype = proto; if (getaddrinfo(server, NULL, &hints, &server_res) != 0) return -1; s = socket(server_res->ai_family, proto, 0); if (s < 0) { if (local) freeaddrinfo(local_res); freeaddrinfo(server_res); return -1; } /* Bind the local address if given a name (with or without --cport) */ if (local) { if (local_port) { struct sockaddr_in *lcladdr; lcladdr = (struct sockaddr_in *)local_res->ai_addr; lcladdr->sin_port = htons(local_port); } if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) { saved_errno = errno; close(s); freeaddrinfo(local_res); freeaddrinfo(server_res); errno = saved_errno; return -1; } freeaddrinfo(local_res); } /* No local name, but --cport given */ else if (local_port) { size_t addrlen; struct sockaddr_storage lcl; /* IPv4 */ if (server_res->ai_family == AF_INET) { struct sockaddr_in *lcladdr = (struct sockaddr_in *) &lcl; lcladdr->sin_family = AF_INET; lcladdr->sin_port = htons(local_port); lcladdr->sin_addr.s_addr = INADDR_ANY; addrlen = sizeof(struct sockaddr_in); } /* IPv6 */ else if (server_res->ai_family == AF_INET6) { struct sockaddr_in6 *lcladdr = (struct sockaddr_in6 *) &lcl; lcladdr->sin6_family = AF_INET6; lcladdr->sin6_port = htons(local_port); lcladdr->sin6_addr = in6addr_any; addrlen = sizeof(struct sockaddr_in6); } /* Unknown protocol */ else { errno = EAFNOSUPPORT; return -1; } if (bind(s, (struct sockaddr *) &lcl, addrlen) < 0) { saved_errno = errno; close(s); freeaddrinfo(server_res); errno = saved_errno; return -1; } } ((struct sockaddr_in *) server_res->ai_addr)->sin_port = htons(port); if (timeout_connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen, timeout) < 0 && errno != EINPROGRESS) { saved_errno = errno; close(s); freeaddrinfo(server_res); errno = saved_errno; return -1; } freeaddrinfo(server_res); return s; }
/* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. * If port is 0, the default port will be used. * Connection_attempts specifies the maximum number of tries (one per * second). If proxy_command is non-NULL, it specifies the command (with %h * and %p substituted for host and port, respectively) to use to contact * the daemon. */ static int ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, struct sockaddr_storage *hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, int want_keepalive) { int on = 1; int oerrno, sock = -1, attempt; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo *ai; debug2("%s", __func__); memset(ntop, 0, sizeof(ntop)); memset(strport, 0, sizeof(strport)); for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ sleep(1); debug("Trying again..."); } /* * Loop through addresses for this host, and try each one in * sequence until the connection succeeds. */ for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { errno = EAFNOSUPPORT; continue; } if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { oerrno = errno; error("%s: getnameinfo failed", __func__); errno = oerrno; continue; } debug("Connecting to %.200s [%.100s] port %s.", host, ntop, strport); /* Create a socket for connecting. */ sock = ssh_create_socket(ai); if (sock < 0) { /* Any error is already output */ errno = 0; continue; } if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, timeout_ms) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; } else { oerrno = errno; debug("connect to address %s port %s: %s", ntop, strport, strerror(errno)); close(sock); sock = -1; errno = oerrno; } } if (sock != -1) break; /* Successful connection. */ } /* Return failure if we didn't get a successful connection. */ if (sock == -1) { error("ssh: connect to host %s port %s: %s", host, strport, errno == 0 ? "failure" : strerror(errno)); return -1; } debug("Connection established."); /* Set SO_KEEPALIVE if requested. */ if (want_keepalive && setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); /* Set the connection. */ if (ssh_packet_set_connection(ssh, sock, sock) == NULL) return -1; /* ssh_packet_set_connection logs error */ return 0; }