Пример #1
0
int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
		     char *tmp,char *hst)
{
  int sock;
  size_t len;
  char *s;
  struct protoent *pt = getprotobyname ("tcp");
  struct sockaddr *sadr = ip_sockaddr (family,adr,adrlen,port,&len);
  sprintf (tmp,"Trying IP address [%s]",ip_sockaddrtostring (sadr));
  mm_log (tmp,NIL);
				/* get a TCP stream */
  if ((sock = socket (sadr->sa_family,SOCK_STREAM,pt ? pt->p_proto : 0)) ==
      INVALID_SOCKET)
    sprintf (tmp,"Unable to create TCP socket (%d)",WSAGetLastError ());
  else {
    wsa_sock_open++;		/* count this socket as open */
				/* open connection */
    if (connect (sock,sadr,len) == SOCKET_ERROR) {
      switch (WSAGetLastError ()) {
      case WSAECONNREFUSED:
	s = "Refused";
	break;
      case WSAENOBUFS:
	s = "Insufficient system resources";
	break;
      case WSAETIMEDOUT:
	s = "Timed out";
	break;
      case WSAEHOSTUNREACH:
	s = "Host unreachable";
	break;
      default:
	s = "Unknown error";
	break;
      }
      sprintf (tmp,"Can't connect to %.80s,%ld: %s (%d)",hst,port,s,
	       WSAGetLastError ());
      tcp_abort (&sock);	/* flush socket */
      sock = INVALID_SOCKET;
    }
  }
  fs_give ((void **) &sadr);
  return sock;			/* return the socket */
}
Пример #2
0
long tcp_isclienthost (char *host)
{
  int family;
  size_t adrlen,sadrlen,len;
  void *adr,*next;
  struct sockaddr *sadr;
  long ret = NIL;
				/* make sure that myClientAddr is set */
  if (tcp_clienthost () && myClientAddr)
				/* get sockaddr of client */
    for (adr = ip_nametoaddr (host,&adrlen,&family,NIL,&next); adr && !ret;
	 adr = ip_nametoaddr (NIL,&adrlen,&family,NIL,&next)) {
				/* build sockaddr of given address */
      sadr = ip_sockaddr (family,adr,adrlen,1,&len);
      if (!strcmp (myClientAddr,ip_sockaddrtostring (sadr))) ret = LONGT;
      fs_give ((void **) &sadr);	/* done with client sockaddr */
    }
  return ret;
}
Пример #3
0
int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
		     char *tmp,int *ctr,char *hst)
{
  int i,ti,sock,flgs;
  size_t len;
  time_t now;
  struct protoent *pt = getprotobyname ("tcp");
  fd_set fds,efds;
  struct timeval tmo;
  struct sockaddr *sadr = ip_sockaddr (family,adr,adrlen,port,&len);
  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
				/* fetid Solaris */
  void *data = (*bn) (BLOCK_SENSITIVE,NIL);
  sprintf (tmp,"Trying IP address [%s]",ip_sockaddrtostring (sadr));
  mm_log (tmp,NIL);
				/* make a socket */
  if ((sock = socket (sadr->sa_family,SOCK_STREAM,pt ? pt->p_proto : 0)) < 0) {
    sprintf (tmp,"Unable to create TCP socket: %s",strerror (errno));
    (*bn) (BLOCK_NONSENSITIVE,data);
  }
  else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */
    sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)",
	     sock,FD_SETSIZE);
    (*bn) (BLOCK_NONSENSITIVE,data);
    close (sock);
    sock = -1;
    errno = EMFILE;
  }

  else {			/* get current socket flags */
    flgs = fcntl (sock,F_GETFL,0);
				/* set non-blocking if want open timeout */
    if (ctr) fcntl (sock,F_SETFL,flgs | FNDELAY);
				/* open connection */
    while ((i = connect (sock,sadr,len)) < 0 && (errno == EINTR));
    (*bn) (BLOCK_NONSENSITIVE,data);
    if (i < 0) switch (errno) {	/* failed? */
    case EAGAIN:		/* DG brain damage */
    case EINPROGRESS:		/* what we expect to happen */
    case EALREADY:		/* or another form of it */
    case EISCONN:		/* restart after interrupt? */
    case EADDRINUSE:		/* restart after interrupt? */
      break;			/* well, not really, it was interrupted */
    default:
      sprintf (tmp,"Can't connect to %.80s,%u: %s",hst,(unsigned int) port,
	       strerror (errno));
      close (sock);		/* flush socket */
      sock = -1;
    }
    if ((sock >= 0) && ctr) {	/* want open timeout? */
      now = time (0);		/* open timeout */
      ti = ttmo_open ? now + ttmo_open : 0;
      tmo.tv_usec = 0;
      FD_ZERO (&fds);		/* initialize selection vector */
      FD_ZERO (&efds);		/* handle errors too */
      FD_SET (sock,&fds);	/* block for error or readable */
      FD_SET (sock,&efds);
      do {			/* block under timeout */
	tmo.tv_sec = ti ? ti - now : 0;
	i = select (sock+1,&fds,NIL,&efds,ti ? &tmo : NIL);
	now = time (0);		/* fake timeout if interrupt & time expired */
	if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
      } while ((i < 0) && (errno == EINTR));
      if (i > 0) {		/* success, make sure really connected */
				/* restore blocking status */
	fcntl (sock,F_SETFL,flgs);
	/* This used to be a zero-byte read(), but that crashes Solaris */
				/* get socket status */
	while (((i = *ctr = read (sock,tmp,1)) < 0) && (errno == EINTR));
      }	
      if (i <= 0) {		/* timeout or error? */
	i = i ? errno : ETIMEDOUT;/* determine error code */
	close (sock);		/* flush socket */
	sock = -1;
	errno = i;		/* return error code */
	sprintf (tmp,"Connection failed to %.80s,%lu: %s",hst,
		 (unsigned long) port,strerror (errno));
      }
    }
  }
  fs_give ((void **) &sadr);
  return sock;			/* return the socket */
}