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