|
Lines 30-35
Link Here
|
| 30 |
#include <stdlib.h> |
30 |
#include <stdlib.h> |
| 31 |
#include <string.h> |
31 |
#include <string.h> |
| 32 |
#include <unistd.h> |
32 |
#include <unistd.h> |
|
|
33 |
#include <sys/un.h> |
| 33 |
|
34 |
|
| 34 |
#include "atomicio.h" |
35 |
#include "atomicio.h" |
| 35 |
#include "dsocks.h" |
36 |
#include "dsocks.h" |
|
Lines 39-46
Link Here
|
| 39 |
const struct addrinfo *, struct addrinfo **); |
40 |
const struct addrinfo *, struct addrinfo **); |
| 40 |
typedef struct hostent *(*gethostbyname_fn)(const char *name); |
41 |
typedef struct hostent *(*gethostbyname_fn)(const char *name); |
| 41 |
|
42 |
|
|
|
43 |
typedef union { |
| 44 |
struct sockaddr any; |
| 45 |
struct sockaddr_in in; |
| 46 |
struct sockaddr_un un; |
| 47 |
} sockaddr_any; |
| 48 |
|
| 49 |
static int _dsocks_domain = AF_UNSPEC; |
| 42 |
static int _dsocks_tor; |
50 |
static int _dsocks_tor; |
| 43 |
static struct sockaddr_in _dsocks_sin, _dsocks_ns; |
51 |
static struct sockaddr_in _dsocks_sin; |
|
|
52 |
static struct sockaddr_un _dsocks_sun; |
| 53 |
static struct sockaddr_in _dsocks_ns; |
| 44 |
static char _dsocks_user[MAXLOGNAME + 1]; |
54 |
static char _dsocks_user[MAXLOGNAME + 1]; |
| 45 |
static char _dsocks_host[MAXHOSTNAMELEN + 1]; |
55 |
static char _dsocks_host[MAXHOSTNAMELEN + 1]; |
| 46 |
static connect_fn _dsocks_connect, _sys_connect; |
56 |
static connect_fn _dsocks_connect, _sys_connect; |
|
Lines 181-197
Link Here
|
| 181 |
connect(int fd, const struct sockaddr *sa, socklen_t len) |
191 |
connect(int fd, const struct sockaddr *sa, socklen_t len) |
| 182 |
{ |
192 |
{ |
| 183 |
struct sockaddr_in sin; |
193 |
struct sockaddr_in sin; |
|
|
194 |
int fd1; |
| 184 |
|
195 |
|
| 185 |
if (sa->sa_family != AF_INET || IS_LOOPBACK(sa)) |
196 |
if (sa->sa_family != AF_INET || IS_LOOPBACK(sa)) |
| 186 |
return ((*_sys_connect)(fd, sa, len)); |
197 |
return ((*_sys_connect)(fd, sa, len)); |
| 187 |
|
198 |
|
| 188 |
memcpy(&sin, sa, sizeof(sin)); |
199 |
memcpy(&sin, sa, sizeof(sin)); |
| 189 |
if ((*_sys_connect)(fd, (struct sockaddr *)&_dsocks_sin, |
200 |
if (_dsocks_domain == AF_UNIX) { |
| 190 |
sizeof(_dsocks_sin)) == -1) { |
201 |
if ((fd1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { |
| 191 |
warnx("(dsocks) couldn't connect to proxy at %s", |
202 |
warnx("(dsocks) couldn't create socket: %s", |
| 192 |
_sin_ntoa(&_dsocks_sin)); |
203 |
strerror(errno)); |
| 193 |
return (-1); |
204 |
return (-1); |
|
|
205 |
} |
| 206 |
if ((*_sys_connect)(fd1, (struct sockaddr *)&_dsocks_sun, |
| 207 |
sizeof(struct sockaddr_un)) == -1) { |
| 208 |
warnx("(dsocks) couldn't connect to proxy at %s: %s", |
| 209 |
_dsocks_sun.sun_path, strerror(errno)); |
| 210 |
close(fd1); |
| 211 |
return (-1); |
| 212 |
} |
| 213 |
if (dup2(fd1, fd) == -1) { |
| 214 |
warnx("(dsocks) couldn't dup socket: %s", |
| 215 |
strerror(errno)); |
| 216 |
close(fd1); |
| 217 |
return (-1); |
| 218 |
} |
| 219 |
close(fd1); |
| 194 |
} |
220 |
} |
|
|
221 |
else { |
| 222 |
if ((*_sys_connect)(fd, (struct sockaddr *)&_dsocks_sin, |
| 223 |
sizeof(struct sockaddr_in)) == -1) { |
| 224 |
warnx("(dsocks) couldn't connect to proxy at %s", |
| 225 |
_sin_ntoa(&_dsocks_sin)); |
| 226 |
return (-1); |
| 227 |
} |
| 228 |
} |
| 195 |
return ((*_dsocks_connect)(fd, (struct sockaddr *)&sin, sizeof(sin))); |
229 |
return ((*_dsocks_connect)(fd, (struct sockaddr *)&sin, sizeof(sin))); |
| 196 |
} |
230 |
} |
| 197 |
|
231 |
|
|
Lines 592-602
Link Here
|
| 592 |
if (getenv(DSOCKS_ENV_TOR) != NULL) { |
626 |
if (getenv(DSOCKS_ENV_TOR) != NULL) { |
| 593 |
_dsocks_tor = 1; |
627 |
_dsocks_tor = 1; |
| 594 |
} |
628 |
} |
| 595 |
if ((env = getenv(DSOCKS_ENV_PROXY)) != NULL) { |
629 |
if ((env = getenv(DSOCKS_ENV_DOMAIN)) != NULL) { |
|
|
630 |
if (!strcmp(env, "UNIX")) |
| 631 |
_dsocks_domain = AF_UNIX; |
| 632 |
else if (!strcmp(env, "INET")) |
| 633 |
_dsocks_domain = AF_INET; |
| 634 |
else |
| 635 |
errx(1, "(dsocks) invalid proxy domain (valid " |
| 636 |
"values are UNIX and INET): %s\n", env); |
| 637 |
} |
| 638 |
env = getenv(DSOCKS_ENV_PROXY); |
| 639 |
if (!env) env = "127.0.0.1"; |
| 640 |
|
| 641 |
if ((_dsocks_domain == AF_UNIX) || |
| 642 |
((_dsocks_domain == AF_UNSPEC) && strchr(env, '/'))) { |
| 643 |
_dsocks_sun.sun_len = sizeof(_dsocks_sun); |
| 644 |
_dsocks_sun.sun_family = _dsocks_domain = AF_UNIX; |
| 645 |
if (strlen(env) >= sizeof(_dsocks_sun.sun_path)) |
| 646 |
errx(1, "(dsocks) server path too long\n"); |
| 647 |
strcpy(_dsocks_sun.sun_path, env); |
| 648 |
} else { |
| 649 |
_dsocks_domain = AF_INET; |
| 596 |
if (_sin_aton(env, &_dsocks_sin, 1080) < 0) |
650 |
if (_sin_aton(env, &_dsocks_sin, 1080) < 0) |
| 597 |
errx(1, "(dsocks) invalid proxy: %s", env); |
651 |
errx(1, "(dsocks) invalid proxy: %s", env); |
| 598 |
} else |
652 |
} |
| 599 |
_sin_aton("127.0.0.1", &_dsocks_sin, 1080); |
|
|
| 600 |
|
653 |
|
| 601 |
if ((env = getenv(DSOCKS_ENV_NAMESERVER)) != NULL) { |
654 |
if ((env = getenv(DSOCKS_ENV_NAMESERVER)) != NULL) { |
| 602 |
if (_sin_aton(env, &_dsocks_ns, 53) < 0) |
655 |
if (_sin_aton(env, &_dsocks_ns, 53) < 0) |