]> jfr.im git - irc/quakenet/newserv.git/blob - proxyscan/proxyscanconnect.c
CHANSERV: reduce reason to 15 chars
[irc/quakenet/newserv.git] / proxyscan / proxyscanconnect.c
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
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;
21 int res=1;
22 unsigned int opt=1;
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) {
38 Error("proxyscan",ERR_ERROR,"Unable to create socket (%d)",errno);
39 return -1;
40 }
41 if (ioctl(fd,FIONBIO,&res)!=0) {
42 close(fd);
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) {
47 close(fd);
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) {
54 close(fd);
55 Error("proxyscan",ERR_WARNING,"Error selecting high port range.");
56 }
57 #endif
58
59 if (connect(fd,(const struct sockaddr *) &u, s)) {
60 if (errno != EINPROGRESS) {
61 close(fd);
62 Error("proxyscan",ERR_ERROR,"Unable to connect socket (%d)",errno);
63 return -1;
64 }
65 }
66
67 return fd;
68 }