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