int open_server( char *hostname, short hostport) { int32 server_ip ; char alertstr[MAXLINELENGTH+1] ; int TCP_IP_resp, cn; /* Look up host */ if( _resolve( hostname, (char **)NULL, &server_ip, 1 ) < 0 ) { /* Resolve error */ sprintf( alertstr, "Cannot find server %s",hostname ) ; alert( alertstr ) ; return -1; } event_loop() ; /* Open socket and bind it to address */ if( ( cn = _TCP_open( server_ip, port, 0, TCPBUFSIZ ) ) < 0 ) { alert( "Could not open a socket") ; return -1; } ndb = (NDB *)NULL; /* Wait for connection to be established */ TCP_IP_resp=_TCP_wait_state( cn, TESTABLISH, TIMEOUT ); if( TCP_IP_resp != E_NORMAL ) { if( TCP_IP_resp=-7 ) { alert( "connection refused by remote server"); } else { alert( "could not connect to remote server, unknown error") ; } _TCP_close( cn, TIMEOUT ) ; byebye(1) ; } return cn ; }
/* * Handle SOCK_STREAM blocking connection. Or non-blocking connect * the first time connect() is called. */ static int tcp_connect (Socket *socket) { DWORD timeout; int status; #if defined(USE_IPV6) if (socket->so_family == AF_INET6) { const struct sockaddr_in6 *la = (const struct sockaddr_in6*) socket->local_addr; const struct sockaddr_in6 *ra = (const struct sockaddr_in6*) socket->remote_addr; if (!_TCP6_open (socket, &ra->sin6_addr, la->sin6_port, ra->sin6_port)) { /* errno already set in _TCP6_open() */ SOCK_DEBUGF ((", %s", socket->tcp_sock->err_msg)); return (-1); } } else #endif if (!_TCP_open (socket, socket->remote_addr->sin_addr, socket->local_addr->sin_port, socket->remote_addr->sin_port)) { /* errno already set in tcp_open() */ SOCK_DEBUGF ((", %s", socket->tcp_sock->err_msg)); return (-1); } /* Don't let tcp_Retransmitter() kill this socket * before our `socket->timeout' expires */ socket->tcp_sock->locflags |= LF_RCVTIMEO; /* We're here only when connect() is called the 1st time * (blocking or non-blocking socket). */ socket->so_state |= SS_ISCONNECTING; timeout = set_timeout (1000 * socket->timeout); if (socket->so_state & SS_NBIO) { /* if user calls getsockopt(SO_ERROR) before calling connect() again */ socket->so_error = EALREADY; socket->nb_timer = timeout; SOCK_DEBUGF ((", EINPROGRESS")); SOCK_ERRNO (EINPROGRESS); return (-1); } /* Handle blocking stream socket connect. * Maybe we should use select_s() instead ? * Maybe set LF_NOCLOSE for all BSD sockets? */ status = _ip_delay0 ((sock_type*)socket->tcp_sock, socket->timeout, (UserHandler)chk_signals, NULL); if (socket->so_error == EHOSTUNREACH) { SOCK_DEBUGF ((", %s", socket->tcp_sock->err_msg ? socket->tcp_sock->err_msg : "no route")); SOCK_ERRNO (EHOSTUNREACH); return (-1); } /* We got an ICMP_UNREACH from someone */ if (socket->so_state & SS_CONN_REFUSED) { socket->so_state &= ~SS_ISCONNECTING; SOCK_DEBUGF ((", ECONNREFUSED")); SOCK_ERRNO (ECONNREFUSED); return (-1); } if (status < 0 && chk_timeout(timeout)) { socket->so_state &= ~SS_ISCONNECTING; SOCK_DEBUGF ((", ETIMEDOUT")); SOCK_ERRNO (ETIMEDOUT); return (-1); } if (status < 0) { socket->so_state &= ~SS_ISCONNECTING; SOCK_DEBUGF ((", ECONNRESET")); SOCK_ERRNO (ECONNRESET); return (-1); } socket->so_state &= ~(SS_UNCONNECTED | SS_ISCONNECTING); socket->so_state |= SS_ISCONNECTED; return (0); }