s/qmail  3.3.23
Next generation secure email transport
timeoutconn.c
Go to the documentation of this file.
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <netinet/in.h>
4 #include <arpa/inet.h>
5 #include "ndelay.h"
6 #include "select.h"
7 #include "error.h"
8 #include "readwrite.h"
9 #include "ip.h"
10 #include "ipalloc.h"
11 #include "byte.h"
12 #include "timeoutconn.h"
13 #include "socket6_if.h"
14 
15 int timeoutconn(int s,struct ip_address *ip,unsigned int port,int timeout)
16 {
17  char ch;
18  struct sockaddr_in sin;
19  char *x;
20  fd_set wfds;
21  struct timeval tv;
22 
23  byte_zero(&sin,sizeof(sin));
24  byte_copy(&sin.sin_addr,4,ip);
25  x = (char *) &sin.sin_port;
26  x[1] = port; port >>= 8; x[0] = port;
27  sin.sin_family = AF_INET;
28 
29  if (ndelay_on(s) == -1) return -1;
30 
31  /* XXX: could bind s */
32 
33  if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) {
34  ndelay_off(s);
35  return 0;
36  }
37  if ((errno != error_inprogress) && (errno != error_wouldblock)) return -1;
38 
39  FD_ZERO(&wfds);
40  FD_SET(s,&wfds);
41  tv.tv_sec = timeout; tv.tv_usec = 0;
42 
43  if (select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1;
44  if (FD_ISSET(s,&wfds)) {
45  int dummy;
46  dummy = sizeof(sin);
47  if (getpeername(s,(struct sockaddr *) &sin,&dummy) == -1) {
48  read(s,&ch,1);
49  return -1;
50  }
51  ndelay_off(s);
52  return 0;
53  }
54 
55  errno = error_timeout; /* note that connect attempt is continuing */
56  return -1;
57 }
58 
59 int timeoutconn6(int s,struct ip6_address *ip,unsigned int port,int timeout,char *ifname)
60 {
61  char ch;
62  struct sockaddr_in6 sin;
63  fd_set wfds;
64  struct timeval tv;
65 
66  byte_zero(&sin,sizeof(sin));
67  byte_copy(&sin.sin6_addr,16,ip);
68  sin.sin6_port = htons(port);
69  sin.sin6_family = AF_INET6;
70  if (ifname) sin.sin6_scope_id = socket_getifidx(ifname);
71 
72  if (ndelay_on(s) == -1) return -1;
73 
74  /* XXX: could bind s */
75 
76  if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) {
77  ndelay_off(s);
78  return 0;
79  }
80  if ((errno != error_inprogress) && (errno != error_wouldblock)) return -1;
81 
82  FD_ZERO(&wfds);
83  FD_SET(s,&wfds);
84  tv.tv_sec = timeout; tv.tv_usec = 0;
85 
86  if (select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1;
87  if (FD_ISSET(s,&wfds)) {
88  int dummy;
89  dummy = sizeof(sin);
90  if (getpeername(s,(struct sockaddr *) &sin,&dummy) == -1) {
91  read(s,&ch,1);
92  return -1;
93  }
94  ndelay_off(s);
95  return 0;
96  }
97 
98  errno = error_timeout; /* note that connect attempt is continuing */
99  return -1;
100 }
101 
102 int timeoutconn46(int fd,struct ip_mx *ix,int port,int timeout)
103 {
104 
105  switch(ix->af) {
106  case AF_INET6: return timeoutconn6(fd,&ix->addr.ip6,port,timeout,0);
107  case AF_INET: return timeoutconn(fd,&ix->addr.ip,port,timeout);
108  }
109 }
int timeoutconn(int s, struct ip_address *ip, unsigned int port, int timeout)
Definition: timeoutconn.c:15
int fd
Definition: idedit.c:16
struct ip_address ip
Definition: ipalloc.h:9
void byte_copy(char *, unsigned int, char *)
Definition: ip.h:12
struct ip_address ip
Definition: dnsptr.c:16
Definition: ipalloc.h:6
int error_wouldblock
Definition: error.c:62
int timeoutconn46(int fd, struct ip_mx *ix, int port, int timeout)
Definition: timeoutconn.c:102
uint32 socket_getifidx(const char *ifname)
Definition: socket6_if.c:16
int errno
Definition: ip.h:11
int timeout
Definition: qmail-remote.c:246
unsigned x
Definition: matchup.c:36
unsigned short af
Definition: ipalloc.h:7
int ndelay_on(int fd)
Definition: ndelay.c:9
int ndelay_off(int)
Definition: ndelay_off.c:9
int timeoutconn6(int s, struct ip6_address *ip, unsigned int port, int timeout, char *ifname)
Definition: timeoutconn.c:59
struct ip6_address ip6
Definition: ipalloc.h:10
void byte_zero(char *, unsigned int)
union ip_mx::@1 addr
int error_timeout
Definition: error.c:48
int error_inprogress
Definition: error.c:55
unsigned long port
Definition: qmail-remote.c:52