mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-26 15:06:04 +03:00
IPv6 support for client (#107)
The iodine client now supports both IPv4 and IPv6 nameservers for sending DNS queries to an IPv4 iodined. The nameserver will transparently handle translation between IP protocols. Windows port needs Vista or later to support IPv6.
This commit is contained in:
parent
8baad91156
commit
a1d88c4f0a
77
src/client.c
77
src/client.c
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#ifdef WINDOWS32
|
#ifdef WINDOWS32
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
#else
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
#include "android_dns.h"
|
#include "android_dns.h"
|
||||||
@ -61,7 +60,7 @@ static void handshake_lazyoff(int dns_fd);
|
|||||||
static int running;
|
static int running;
|
||||||
static const char *password;
|
static const char *password;
|
||||||
|
|
||||||
static struct sockaddr_in nameserv;
|
static struct sockaddr_storage nameserv;
|
||||||
static struct sockaddr_in raw_serv;
|
static struct sockaddr_in raw_serv;
|
||||||
static const char *topdomain;
|
static const char *topdomain;
|
||||||
|
|
||||||
@ -149,75 +148,9 @@ client_get_conn()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
client_set_nameserver(const char *cp, int port)
|
client_set_nameserver(struct sockaddr_storage *addr, int addrlen)
|
||||||
{
|
{
|
||||||
#ifdef ANDROID
|
memcpy(&nameserv, addr, addrlen);
|
||||||
struct addrinfo hints, *result, *p;
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
|
|
||||||
char sport[10];
|
|
||||||
sprintf(sport, "%d", port);
|
|
||||||
|
|
||||||
getaddrinfo(cp, sport, &hints, &result);
|
|
||||||
if (result == NULL)
|
|
||||||
errx(1, "Cannot resolve %s:%s (no network?)", cp, sport);
|
|
||||||
else {
|
|
||||||
for (p = result;p != NULL; p = p->ai_next) {
|
|
||||||
if (p->ai_family == AF_INET) { /* IPv4 */
|
|
||||||
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
|
|
||||||
memset(&nameserv, 0, sizeof(nameserv));
|
|
||||||
nameserv.sin_family = AF_INET;
|
|
||||||
nameserv.sin_port = htons(port);
|
|
||||||
nameserv.sin_addr = ipv4->sin_addr;
|
|
||||||
freeaddrinfo(result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freeaddrinfo(result);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
struct in_addr addr;
|
|
||||||
|
|
||||||
if (inet_aton(cp, &addr) != 1) {
|
|
||||||
/* try resolving if a domain is given */
|
|
||||||
struct hostent *host;
|
|
||||||
const char *err;
|
|
||||||
host = gethostbyname(cp);
|
|
||||||
if (host != NULL && h_errno > 0) {
|
|
||||||
int i = 0;
|
|
||||||
while (host->h_addr_list[i] != 0) {
|
|
||||||
addr = *(struct in_addr *) host->h_addr_list[i++];
|
|
||||||
fprintf(stderr, "Resolved %s to %s\n", cp, inet_ntoa(addr));
|
|
||||||
goto setaddr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef WINDOWS32
|
|
||||||
err = hstrerror(h_errno);
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
DWORD wserr = WSAGetLastError();
|
|
||||||
switch (wserr) {
|
|
||||||
case WSAHOST_NOT_FOUND:
|
|
||||||
err = "Host not found";
|
|
||||||
break;
|
|
||||||
case WSANO_DATA:
|
|
||||||
err = "No data record found";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = "Unknown error";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* !WINDOWS32 */
|
|
||||||
errx(1, "error resolving nameserver '%s': %s", cp, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
setaddr:
|
|
||||||
memset(&nameserv, 0, sizeof(nameserv));
|
|
||||||
nameserv.sin_family = AF_INET;
|
|
||||||
nameserv.sin_port = htons(port);
|
|
||||||
nameserv.sin_addr = addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -625,12 +558,12 @@ read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q)
|
|||||||
Returns >0 on correct replies; value is #valid bytes in *buf.
|
Returns >0 on correct replies; value is #valid bytes in *buf.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct sockaddr_in from;
|
struct sockaddr_storage from;
|
||||||
char data[64*1024];
|
char data[64*1024];
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
addrlen = sizeof(struct sockaddr);
|
addrlen = sizeof(from);
|
||||||
if ((r = recvfrom(dns_fd, data, sizeof(data), 0,
|
if ((r = recvfrom(dns_fd, data, sizeof(data), 0,
|
||||||
(struct sockaddr*)&from, &addrlen)) < 0) {
|
(struct sockaddr*)&from, &addrlen)) < 0) {
|
||||||
warn("recvfrom");
|
warn("recvfrom");
|
||||||
|
@ -23,7 +23,7 @@ void client_stop();
|
|||||||
enum connection client_get_conn();
|
enum connection client_get_conn();
|
||||||
const char *client_get_raw_addr();
|
const char *client_get_raw_addr();
|
||||||
|
|
||||||
void client_set_nameserver(const char *cp, int port);
|
void client_set_nameserver(struct sockaddr_storage *, int);
|
||||||
void client_set_topdomain(const char *cp);
|
void client_set_topdomain(const char *cp);
|
||||||
void client_set_password(const char *cp);
|
void client_set_password(const char *cp);
|
||||||
void set_qtype(char *qtype);
|
void set_qtype(char *qtype);
|
||||||
|
58
src/common.c
58
src/common.c
@ -42,6 +42,8 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SETCON
|
#ifdef HAVE_SETCON
|
||||||
@ -112,20 +114,39 @@ check_superuser(void (*usage_fn)(void))
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
open_dns(int localport, in_addr_t listen_ip)
|
get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_storage *out)
|
||||||
|
{
|
||||||
|
struct addrinfo hints, *addr;
|
||||||
|
int res;
|
||||||
|
char portnum[8];
|
||||||
|
|
||||||
|
memset(portnum, 0, sizeof(portnum));
|
||||||
|
snprintf(portnum, sizeof(portnum) - 1, "%d", port);
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = addr_family;
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG | flags;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
|
||||||
|
res = getaddrinfo(host, portnum, &hints, &addr);
|
||||||
|
if (res == 0) {
|
||||||
|
int addrlen = addr->ai_addrlen;
|
||||||
|
/* Grab first result */
|
||||||
|
memcpy(out, addr->ai_addr, addr->ai_addrlen);
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
return addrlen;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
if ((fd = socket(sockaddr->ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(localport);
|
|
||||||
/* listen_ip already in network byte order from inet_addr, or 0 */
|
|
||||||
addr.sin_addr.s_addr = listen_ip;
|
|
||||||
|
|
||||||
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
|
||||||
fprintf(stderr, "got fd %d\n", fd);
|
|
||||||
err(1, "socket");
|
err(1, "socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,14 +167,27 @@ open_dns(int localport, in_addr_t listen_ip)
|
|||||||
setsockopt(fd, IPPROTO_IP, IP_OPT_DONT_FRAG, (const void*) &flag, sizeof(flag));
|
setsockopt(fd, IPPROTO_IP, IP_OPT_DONT_FRAG, (const void*) &flag, sizeof(flag));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
|
if(bind(fd, (struct sockaddr*) sockaddr, sockaddr_len) < 0)
|
||||||
err(1, "bind");
|
err(1, "bind");
|
||||||
|
|
||||||
fprintf(stderr, "Opened UDP socket\n");
|
fprintf(stderr, "Opened IPv%d UDP socket\n", sockaddr->ss_family == AF_INET6 ? 6 : 4);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
open_dns_from_host(char *host, int port, int addr_family, int flags)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
int addrlen;
|
||||||
|
|
||||||
|
addrlen = get_addr(host, port, addr_family, flags, &addr);
|
||||||
|
if (addrlen < 0)
|
||||||
|
return addrlen;
|
||||||
|
|
||||||
|
return open_dns(&addr, addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
close_dns(int fd)
|
close_dns(int fd)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ struct query {
|
|||||||
unsigned short rcode;
|
unsigned short rcode;
|
||||||
unsigned short id;
|
unsigned short id;
|
||||||
struct in_addr destination;
|
struct in_addr destination;
|
||||||
struct sockaddr from;
|
struct sockaddr_storage from;
|
||||||
int fromlen;
|
int fromlen;
|
||||||
unsigned short id2;
|
unsigned short id2;
|
||||||
struct sockaddr from2;
|
struct sockaddr from2;
|
||||||
@ -107,7 +107,9 @@ enum connection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void check_superuser(void (*usage_fn)(void));
|
void check_superuser(void (*usage_fn)(void));
|
||||||
int open_dns(int, in_addr_t);
|
int get_addr(char *, int, int, int, struct sockaddr_storage *);
|
||||||
|
int open_dns(struct sockaddr_storage *, size_t);
|
||||||
|
int open_dns_from_host(char *host, int port, int addr_family, int flags);
|
||||||
void close_dns(int);
|
void close_dns(int);
|
||||||
|
|
||||||
void do_chroot(char *);
|
void do_chroot(char *);
|
||||||
|
24
src/iodine.c
24
src/iodine.c
@ -32,6 +32,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -111,7 +112,7 @@ version() {
|
|||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *nameserv_addr;
|
char *nameserv_host;
|
||||||
char *topdomain;
|
char *topdomain;
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
@ -134,8 +135,10 @@ main(int argc, char **argv)
|
|||||||
int selecttimeout;
|
int selecttimeout;
|
||||||
int hostname_maxlen;
|
int hostname_maxlen;
|
||||||
int rtable = 0;
|
int rtable = 0;
|
||||||
|
struct sockaddr_storage nameservaddr;
|
||||||
|
int nameservaddr_len;
|
||||||
|
|
||||||
nameserv_addr = NULL;
|
nameserv_host = NULL;
|
||||||
topdomain = NULL;
|
topdomain = NULL;
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
pw = NULL;
|
pw = NULL;
|
||||||
@ -257,11 +260,11 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 1:
|
case 1:
|
||||||
nameserv_addr = get_resolvconf_addr();
|
nameserv_host = get_resolvconf_addr();
|
||||||
topdomain = strdup(argv[0]);
|
topdomain = strdup(argv[0]);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
nameserv_addr = argv[0];
|
nameserv_host = argv[0];
|
||||||
topdomain = strdup(argv[1]);
|
topdomain = strdup(argv[1]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -275,8 +278,13 @@ main(int argc, char **argv)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameserv_addr) {
|
if (nameserv_host) {
|
||||||
client_set_nameserver(nameserv_addr, DNS_PORT);
|
nameservaddr_len = get_addr(nameserv_host, DNS_PORT, AF_UNSPEC, 0, &nameservaddr);
|
||||||
|
if (nameservaddr_len < 0) {
|
||||||
|
errx(1, "Cannot lookup nameserver '%s': %s ",
|
||||||
|
nameserv_host, gai_strerror(nameservaddr_len));
|
||||||
|
}
|
||||||
|
client_set_nameserver(&nameservaddr, nameservaddr_len);
|
||||||
} else {
|
} else {
|
||||||
warnx("No nameserver found - not connected to any network?\n");
|
warnx("No nameserver found - not connected to any network?\n");
|
||||||
usage();
|
usage();
|
||||||
@ -323,7 +331,7 @@ main(int argc, char **argv)
|
|||||||
retval = 1;
|
retval = 1;
|
||||||
goto cleanup1;
|
goto cleanup1;
|
||||||
}
|
}
|
||||||
if ((dns_fd = open_dns(0, INADDR_ANY)) == -1) {
|
if ((dns_fd = open_dns_from_host(NULL, 53, nameservaddr.ss_family, AI_PASSIVE)) < 0) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
goto cleanup2;
|
goto cleanup2;
|
||||||
}
|
}
|
||||||
@ -338,7 +346,7 @@ main(int argc, char **argv)
|
|||||||
signal(SIGTERM, sighandler);
|
signal(SIGTERM, sighandler);
|
||||||
|
|
||||||
fprintf(stderr, "Sending DNS queries for %s to %s\n",
|
fprintf(stderr, "Sending DNS queries for %s to %s\n",
|
||||||
topdomain, nameserv_addr);
|
topdomain, nameserv_host);
|
||||||
|
|
||||||
if (client_handshake(dns_fd, raw_mode, autodetect_frag_size, max_downstream_frag_size)) {
|
if (client_handshake(dns_fd, raw_mode, autodetect_frag_size, max_downstream_frag_size)) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
|
@ -221,7 +221,7 @@ send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q)
|
|||||||
inet_ntoa(tempin->sin_addr), cmd, len);
|
inet_ntoa(tempin->sin_addr), cmd, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto(fd, packet, len, 0, &q->from, q->fromlen);
|
sendto(fd, packet, len, 0, (struct sockaddr *) &q->from, q->fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2241,7 +2241,7 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
in_addr_t listen_ip;
|
char *listen_ip;
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
#endif
|
#endif
|
||||||
@ -2267,6 +2267,8 @@ main(int argc, char **argv)
|
|||||||
int ns_get_externalip;
|
int ns_get_externalip;
|
||||||
int retval;
|
int retval;
|
||||||
int max_idle_time = 0;
|
int max_idle_time = 0;
|
||||||
|
struct sockaddr_storage dnsaddr;
|
||||||
|
int dnsaddr_len;
|
||||||
#ifdef HAVE_SYSTEMD
|
#ifdef HAVE_SYSTEMD
|
||||||
int nb_fds;
|
int nb_fds;
|
||||||
#endif
|
#endif
|
||||||
@ -2283,7 +2285,7 @@ main(int argc, char **argv)
|
|||||||
bind_fd = 0;
|
bind_fd = 0;
|
||||||
mtu = 1130; /* Very many relays give fragsize 1150 or slightly
|
mtu = 1130; /* Very many relays give fragsize 1150 or slightly
|
||||||
higher for NULL; tun/zlib adds ~17 bytes. */
|
higher for NULL; tun/zlib adds ~17 bytes. */
|
||||||
listen_ip = INADDR_ANY;
|
listen_ip = NULL;
|
||||||
port = 53;
|
port = 53;
|
||||||
ns_ip = INADDR_ANY;
|
ns_ip = INADDR_ANY;
|
||||||
ns_get_externalip = 0;
|
ns_get_externalip = 0;
|
||||||
@ -2349,7 +2351,7 @@ main(int argc, char **argv)
|
|||||||
mtu = atoi(optarg);
|
mtu = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
listen_ip = inet_addr(optarg);
|
listen_ip = optarg;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
port = atoi(optarg);
|
port = atoi(optarg);
|
||||||
@ -2439,23 +2441,6 @@ main(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bind_enable) {
|
|
||||||
if (bind_port < 1 || bind_port > 65535) {
|
|
||||||
warnx("Bad DNS server port number given.");
|
|
||||||
usage();
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
/* Avoid forwarding loops */
|
|
||||||
if (bind_port == port && (listen_ip == INADDR_ANY || listen_ip == htonl(0x7f000001L))) {
|
|
||||||
warnx("Forward port is same as listen port (%d), will create a loop!", bind_port);
|
|
||||||
fprintf(stderr, "Use -l to set listen ip to avoid this.\n");
|
|
||||||
usage();
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
fprintf(stderr, "Requests for domains outside of %s will be forwarded to port %d\n",
|
|
||||||
topdomain, bind_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port != 53) {
|
if (port != 53) {
|
||||||
fprintf(stderr, "ALERT! Other dns servers expect you to run on port 53.\n");
|
fprintf(stderr, "ALERT! Other dns servers expect you to run on port 53.\n");
|
||||||
fprintf(stderr, "You must manually forward port 53 to port %d for things to work.\n", port);
|
fprintf(stderr, "You must manually forward port 53 to port %d for things to work.\n", port);
|
||||||
@ -2467,11 +2452,30 @@ main(int argc, char **argv)
|
|||||||
foreground = 1;
|
foreground = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen_ip == INADDR_NONE) {
|
dnsaddr_len = get_addr(listen_ip, port, AF_INET, AI_PASSIVE | AI_NUMERICHOST, &dnsaddr);
|
||||||
|
if (dnsaddr_len < 0) {
|
||||||
warnx("Bad IP address to listen on.");
|
warnx("Bad IP address to listen on.");
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bind_enable) {
|
||||||
|
in_addr_t dns_ip = ((struct sockaddr_in *) &dnsaddr)->sin_addr.s_addr;
|
||||||
|
if (bind_port < 1 || bind_port > 65535) {
|
||||||
|
warnx("Bad DNS server port number given.");
|
||||||
|
usage();
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
/* Avoid forwarding loops */
|
||||||
|
if (bind_port == port && (dns_ip == INADDR_ANY || dns_ip == htonl(0x7f000001L))) {
|
||||||
|
warnx("Forward port is same as listen port (%d), will create a loop!", bind_port);
|
||||||
|
fprintf(stderr, "Use -l to set listen ip to avoid this.\n");
|
||||||
|
usage();
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Requests for domains outside of %s will be forwarded to port %d\n",
|
||||||
|
topdomain, bind_port);
|
||||||
|
}
|
||||||
|
|
||||||
if (ns_get_externalip) {
|
if (ns_get_externalip) {
|
||||||
struct in_addr extip;
|
struct in_addr extip;
|
||||||
int res = get_external_ip(&extip);
|
int res = get_external_ip(&extip);
|
||||||
@ -2524,7 +2528,7 @@ main(int argc, char **argv)
|
|||||||
dnsd_fd = SD_LISTEN_FDS_START;
|
dnsd_fd = SD_LISTEN_FDS_START;
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
if ((dnsd_fd = open_dns(port, listen_ip)) == -1) {
|
if ((dnsd_fd = open_dns(&dnsaddr, dnsaddr_len)) < 0) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
goto cleanup2;
|
goto cleanup2;
|
||||||
}
|
}
|
||||||
@ -2532,7 +2536,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (bind_enable) {
|
if (bind_enable) {
|
||||||
if ((bind_fd = open_dns(0, INADDR_ANY)) == -1) {
|
if ((bind_fd = open_dns_from_host(NULL, 0, AF_INET, 0)) < 0) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
goto cleanup3;
|
goto cleanup3;
|
||||||
}
|
}
|
||||||
|
18
src/tun.c
18
src/tun.c
@ -29,9 +29,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS32
|
#ifdef WINDOWS32
|
||||||
#include <winsock2.h>
|
|
||||||
#include <winioctl.h>
|
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
#include <winioctl.h>
|
||||||
|
|
||||||
HANDLE dev_handle;
|
HANDLE dev_handle;
|
||||||
struct tun_data data;
|
struct tun_data data;
|
||||||
@ -300,7 +299,7 @@ DWORD WINAPI tun_reader(LPVOID arg)
|
|||||||
WaitForSingleObject(olpd.hEvent, INFINITE);
|
WaitForSingleObject(olpd.hEvent, INFINITE);
|
||||||
res = GetOverlappedResult(dev_handle, &olpd, (LPDWORD) &len, FALSE);
|
res = GetOverlappedResult(dev_handle, &olpd, (LPDWORD) &len, FALSE);
|
||||||
res = sendto(sock, buf, len, 0, (struct sockaddr*) &(tun->addr),
|
res = sendto(sock, buf, len, 0, (struct sockaddr*) &(tun->addr),
|
||||||
sizeof(struct sockaddr_in));
|
tun->addrlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +312,8 @@ open_tun(const char *tun_device)
|
|||||||
char adapter[256];
|
char adapter[256];
|
||||||
char tapfile[512];
|
char tapfile[512];
|
||||||
int tunfd;
|
int tunfd;
|
||||||
in_addr_t local;
|
struct sockaddr_storage localsock;
|
||||||
|
int localsock_len;
|
||||||
|
|
||||||
memset(adapter, 0, sizeof(adapter));
|
memset(adapter, 0, sizeof(adapter));
|
||||||
memset(if_name, 0, sizeof(if_name));
|
memset(if_name, 0, sizeof(if_name));
|
||||||
@ -341,14 +341,12 @@ open_tun(const char *tun_device)
|
|||||||
* A thread does blocking reads on tun device and
|
* A thread does blocking reads on tun device and
|
||||||
* sends data as udp to this socket */
|
* sends data as udp to this socket */
|
||||||
|
|
||||||
local = htonl(0x7f000001); /* 127.0.0.1 */
|
localsock_len = get_addr("127.0.0.1", 55353, AF_INET, 0, &localsock);
|
||||||
tunfd = open_dns(55353, local);
|
tunfd = open_dns(&localsock, localsock_len);
|
||||||
|
|
||||||
data.tun = dev_handle;
|
data.tun = dev_handle;
|
||||||
memset(&(data.addr), 0, sizeof(data.addr));
|
memcpy(&(data.addr), &localsock, localsock_len);
|
||||||
data.addr.sin_family = AF_INET;
|
data.addrlen = localsock_len;
|
||||||
data.addr.sin_port = htons(55353);
|
|
||||||
data.addr.sin_addr.s_addr = local;
|
|
||||||
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tun_reader, &data, 0, NULL);
|
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tun_reader, &data, 0, NULL);
|
||||||
|
|
||||||
return tunfd;
|
return tunfd;
|
||||||
|
@ -17,11 +17,20 @@
|
|||||||
#ifndef __FIX_WINDOWS_H__
|
#ifndef __FIX_WINDOWS_H__
|
||||||
#define __FIX_WINDOWS_H__
|
#define __FIX_WINDOWS_H__
|
||||||
|
|
||||||
|
#include <w32api.h>
|
||||||
|
/* Need Vista or Later to get IPv6 support */
|
||||||
|
#undef WINVER
|
||||||
|
#undef _WIN32_WINDOWS
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define WINVER WindowsVista
|
||||||
|
#define _WIN32_WINDOWS WindowsVista
|
||||||
|
#define _WIN32_WINNT WindowsVista
|
||||||
|
|
||||||
typedef unsigned int in_addr_t;
|
typedef unsigned int in_addr_t;
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <windns.h>
|
#include <windns.h>
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
@ -94,7 +103,8 @@ DWORD WINAPI tun_reader(LPVOID arg);
|
|||||||
struct tun_data {
|
struct tun_data {
|
||||||
HANDLE tun;
|
HANDLE tun;
|
||||||
int sock;
|
int sock;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_storage addr;
|
||||||
|
int addrlen;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user