]>
Commit | Line | Data |
---|---|---|
c86edd1d Q |
1 | /* proxyscanconnect: handle connections etc. */ |
2 | ||
3 | #include "proxyscan.h" | |
4 | #include <stdlib.h> | |
e7e7312d | 5 | #include <unistd.h> |
c86edd1d Q |
6 | #include <sys/types.h> |
7 | #include <sys/socket.h> | |
8 | #include <netinet/in.h> | |
9 | #include <errno.h> | |
10 | #include "../core/error.h" | |
11 | #include <sys/ioctl.h> | |
12 | #include <string.h> | |
13 | ||
3e986f5e CP |
14 | int createconnectsocket(struct irc_in_addr *ip, int socknum) { |
15 | union { | |
16 | struct sockaddr_in sin; | |
17 | struct sockaddr_in6 sin6; | |
18 | } u; | |
19 | ||
20 | int proto; | |
21 | int s; | |
c86edd1d Q |
22 | int res=1; |
23 | unsigned int opt=1; | |
3e986f5e CP |
24 | int fd; |
25 | ||
26 | if(irc_in_addr_is_ipv4(ip)) { | |
27 | s = sizeof(u.sin); | |
28 | proto=u.sin.sin_family=AF_INET; | |
29 | u.sin.sin_port=htons(socknum); | |
30 | u.sin.sin_addr.s_addr=htonl(irc_in_addr_v4_to_int(ip)); | |
31 | } else { | |
32 | s = sizeof(u.sin6); | |
33 | proto=u.sin6.sin6_family=AF_INET6; | |
34 | u.sin6.sin6_port=htons(socknum); | |
35 | memcpy(&u.sin6.sin6_addr.s6_addr, ip->in6_16, sizeof(ip->in6_16)); | |
36 | } | |
37 | ||
38 | if ((fd=socket(proto,SOCK_STREAM,0))<0) { | |
c86edd1d Q |
39 | Error("proxyscan",ERR_ERROR,"Unable to create socket (%d)",errno); |
40 | return -1; | |
41 | } | |
42 | if (ioctl(fd,FIONBIO,&res)!=0) { | |
1afe9510 | 43 | close(fd); |
c86edd1d Q |
44 | Error("proxyscan",ERR_ERROR,"Unable to make socket nonblocking"); |
45 | return -1; | |
46 | } | |
47 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &opt, sizeof(opt))!=0) { | |
1afe9510 | 48 | close(fd); |
c86edd1d Q |
49 | Error("proxyscan",ERR_ERROR,"Unable to set SO_REUSEADDR on scan socket."); |
50 | return -1; | |
51 | } | |
52 | #ifdef __FreeBSD__ | |
53 | opt=IP_PORTRANGE_HIGH; | |
54 | if (setsockopt(fd, IPPROTO_IP, IP_PORTRANGE, (char *) &opt, sizeof(opt))!=0) { | |
1afe9510 | 55 | close(fd); |
c86edd1d Q |
56 | Error("proxyscan",ERR_WARNING,"Error selecting high port range."); |
57 | } | |
58 | #endif | |
3e986f5e CP |
59 | |
60 | if (connect(fd,(const struct sockaddr *) &u, s)) { | |
c86edd1d | 61 | if (errno != EINPROGRESS) { |
1afe9510 | 62 | close(fd); |
c86edd1d Q |
63 | Error("proxyscan",ERR_ERROR,"Unable to connect socket (%d)",errno); |
64 | return -1; | |
65 | } | |
3e986f5e CP |
66 | } |
67 | ||
c86edd1d Q |
68 | return fd; |
69 | } |