]> jfr.im git - irc/quakenet/newserv.git/blob - proxyscan/proxyscanconnect.c
Merge default.
[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 Error("proxyscan",ERR_ERROR,"Unable to make socket nonblocking");
43 return -1;
44 }
45 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &opt, sizeof(opt))!=0) {
46 Error("proxyscan",ERR_ERROR,"Unable to set SO_REUSEADDR on scan socket.");
47 return -1;
48 }
49 #ifdef __FreeBSD__
50 opt=IP_PORTRANGE_HIGH;
51 if (setsockopt(fd, IPPROTO_IP, IP_PORTRANGE, (char *) &opt, sizeof(opt))!=0) {
52 Error("proxyscan",ERR_WARNING,"Error selecting high port range.");
53 }
54 #endif
55
56 if (connect(fd,(const struct sockaddr *) &u, s)) {
57 if (errno != EINPROGRESS) {
58 Error("proxyscan",ERR_ERROR,"Unable to connect socket (%d)",errno);
59 return -1;
60 }
61 }
62
63 return fd;
64 }