]> jfr.im git - irc/quakenet/newserv.git/blame - proxyscan/proxyscanconnect.c
Merge pull request #132 from retropc/lua_country
[irc/quakenet/newserv.git] / proxyscan / proxyscanconnect.c
CommitLineData
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
16int 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}