]> jfr.im git - irc/quakenet/newserv.git/blob - proxyscan/proxyscanconnect.c
GLINES: fix null pointer deref in trustgline / trustungline
[irc/quakenet/newserv.git] / proxyscan / proxyscanconnect.c
1 /* proxyscanconnect: handle connections etc. */
2
3 #include "proxyscan.h"
4 #include <stdlib.h>
5 #include <unistd.h>
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
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;
22 int res=1;
23 unsigned int opt=1;
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) {
39 Error("proxyscan",ERR_ERROR,"Unable to create socket (%d)",errno);
40 return -1;
41 }
42 if (ioctl(fd,FIONBIO,&res)!=0) {
43 close(fd);
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) {
48 close(fd);
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) {
55 close(fd);
56 Error("proxyscan",ERR_WARNING,"Error selecting high port range.");
57 }
58 #endif
59
60 if (connect(fd,(const struct sockaddr *) &u, s)) {
61 if (errno != EINPROGRESS) {
62 close(fd);
63 Error("proxyscan",ERR_ERROR,"Unable to connect socket (%d)",errno);
64 return -1;
65 }
66 }
67
68 return fd;
69 }