hostname.c
资源名称:socks5.zip [点击查看]
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:12k
源码类别:
代理服务器
开发平台:
Unix_Linux
- /* Copyright (c) 1995,1996,1997 NEC Corporation. All rights reserved. */
- /* */
- /* The redistribution, use and modification in source or binary forms of */
- /* this software is subject to the conditions set forth in the copyright */
- /* document ("Copyright") included with this distribution. */
- /*
- * $Id: hostname.c,v 1.31.4.6 1998/11/18 17:39:12 wlu Exp $
- */
- #include "socks5p.h"
- #include "protocol.h"
- #include "addr.h"
- #include "wrap.h"
- #include "log.h"
- #define S5_HOSTLIST_SIZE 256
- #define S5_HOSTALIASES_SIZE 16
- #define S5_FAKEHOSTFILE "/.s5fakehost"
- int lsInWrapHostname = 0;
- int fd = -1;
- /* local array of host address list and aliases list */
- static struct in_addr host_addr[S5_HOSTLIST_SIZE];
- static char host_aliases[S5_HOSTALIASES_SIZE][S5_HOSTNAME_SIZE];
- /* The address of unresolved host will be of the format "0.0.0.i", where i */
- /* ranges from 1 to 254, pretty simple... */
- #define FAKEPREFIX "0.0.0."
- static int SetReadLock(int lock) {
- struct flock locks;
- locks.l_type = (lock?F_RDLCK:F_UNLCK);
- locks.l_start = 0;
- locks.l_whence = SEEK_SET;
- locks.l_len = 0;
- return fcntl(fd, F_SETLKW, &locks);
- }
- static int SetWriteLock(int lock) {
- struct flock locks;
- locks.l_type = (lock?F_WRLCK:F_UNLCK);
- locks.l_start = 0;
- locks.l_whence = SEEK_SET;
- locks.l_len = 0;
- return fcntl(fd, F_SETLKW, &locks);
- }
- #define S_ISRW(mode) (((mode)&(S_IREAD | S_IWRITE)) == (S_IREAD | S_IWRITE))
- static void FakeHostInit(void) {
- int i, j, flags;
- struct stat sbuf;
- char filename[1024], hostname[S5_HOSTNAME_SIZE], *tmp;
- if (fd > 0) return;
- if ((tmp = getenv("HOME"))) {
- i = MIN(strlen(tmp)+1, sizeof(filename));
- strncpy(filename, tmp, i);
- filename[i-1] = ' ';
- } else strcpy(filename, "/tmp");
- j = strlen(filename);
- i = MIN(strlen(S5_FAKEHOSTFILE)+1, sizeof(filename)-j);
- strncat(filename, S5_FAKEHOSTFILE, i);
- filename[i+j-1] = ' ';
- if (!lstat(filename, &sbuf)) {
- if (sbuf.st_size != 255*sizeof(hostname)+sizeof(int) || !S_ISRW(sbuf.st_mode)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "FakeHostInit: fakehost file (%s) has been changed", filename);
- flags = O_RDWR | O_CREAT | O_TRUNC | O_EXCL;
- } else if (S_ISLNK(sbuf.st_mode) && geteuid() != sbuf.st_uid) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "FakeHostInit: fakehost file (%s) is a link", filename);
- flags = O_RDWR | O_CREAT | O_TRUNC | O_EXCL;
- } else flags = O_RDWR;
- } else flags = O_RDWR | O_CREAT | O_TRUNC | O_EXCL;
- while ((fd = open(filename, flags, 0600)) < 0) {
- if (errno != EINTR && errno != EAGAIN) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "FakeHostInit: open fakehost file (%s) failed %m", filename);
- return;
- }
- }
- if (!(flags & O_CREAT)) return;
- SetWriteLock(1);
- i = 0;
- j = sizeof(int);
- lseek(fd, 0, SEEK_SET);
- if (REAL(write)(fd, (char *)&i, j) != j) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "FakeHostInit: write fakehost file failed %m");
- REAL(close)(fd);
- fd = -1;
- return;
- }
- memset(hostname, 0, sizeof(hostname));
- for (i = 0; i < 255; i++) {
- if (REAL(write)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "FakeHostInit: write fakehost file failed %m");
- REAL(close)(fd);
- fd = -1;
- return;
- }
- }
- SetWriteLock(0);
- }
- static int GetFakeHost(const char *name) {
- int i, j;
- char hostname[S5_HOSTNAME_SIZE];
- FakeHostInit();
- if (fd <= 0) return -1;
- SetWriteLock(1);
- lseek(fd, 0, SEEK_SET);
- i = 0;
- if (REAL(read)(fd, (char *)&i, sizeof(int)) != sizeof(int)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetFakeHost: read table failed %m");
- SetWriteLock(0);
- return -1;
- }
- for (j = 1; j < 256; j++) {
- if (REAL(read)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetFakeHost: read table failed %m");
- SetWriteLock(0);
- return -1;
- }
- if (hostname[0] == ' ' || !strcasecmp(name, hostname)) break;
- }
- if (j == 256 || hostname[0] == ' ') {
- i++;
- if (i == 256) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(20), 0, "GetFakeHost: FAKE table is recycled");
- i = 1;
- j = i;
- } else j = i;
- lseek(fd, 0, SEEK_SET);
- if (REAL(write)(fd, (char *)&i, sizeof(int)) != sizeof(int)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetFakeHost: write table failed %m");
- SetWriteLock(0);
- return -1;
- }
- memset(hostname, 0, sizeof(hostname));
- strncpy(hostname, name, MIN(strlen(name), S5_HOSTNAME_SIZE-1));
- hostname[MIN(strlen(name), S5_HOSTNAME_SIZE-1)] = ' ';
- lseek(fd, (j-1)*S5_HOSTNAME_SIZE+sizeof(int), SEEK_SET);
- if (REAL(write)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetFakeHost: write table failed %m");
- SetWriteLock(0);
- return -1;
- }
- }
- SetWriteLock(0);
- return j;
- }
- static void HostentCopy(struct in_addr **addr_list, char **aliases, const struct hostent *h) {
- int i;
- for (i = 0; i < S5_HOSTALIASES_SIZE; i++) {
- if (h->h_aliases[i] == NULL) break;
- strncpy(host_aliases[i], h->h_aliases[i], MIN(strlen(h->h_aliases[i]), S5_HOSTNAME_SIZE-1));
- host_aliases[i][MIN(strlen(h->h_aliases[i]), S5_HOSTNAME_SIZE-1)] = ' ';
- aliases[i] = (char *)host_aliases[i];
- }
- aliases[i] = NULL;
- for (i = 0; i < S5_HOSTLIST_SIZE; i++) {
- if (h->h_addr_list[i] == NULL) break;
- memcpy((char *)&host_addr[i], h->h_addr_list[i], sizeof(struct in_addr));
- addr_list[i] = &host_addr[i];
- }
- addr_list[i] = NULL;
- }
- /* wrapper around the gethostbyname call. */
- /* similar to gethostbyname() except for: */
- /* *** if gethostbyname() fails, then it returns a pointer to a hostent */
- /* structure filled with a special value, so that SOCKSxxxxxx() will */
- /* realize that this host was unresolved and fill in the protocol */
- /* accordingly... */
- /* */
- /* returns a pointer to a gethostent structure on success; NULL on failure */
- struct hostent *LIBPREFIX(gethostbyname)(const char *name) {
- static struct in_addr special_addr, *my_addr_list[S5_HOSTLIST_SIZE+1];
- static char my_name[MAXNAMELEN], *my_aliases[S5_HOSTALIASES_SIZE+1];
- static struct hostent h;
- struct hostent *hp;
- char *local, *fake;
- int hlen, i;
- #ifdef FOR_SHARED_LIBRARY
- if (lsInRLDFunctions || lsInWrapFunction || lsInWrapHostname) return REAL(gethostbyname)(name);
- #endif
- lsInWrapFunction = 1;
- lsInWrapHostname = 1;
- LIBPREFIX2(init)("libsocks5");
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS gethostbyname: looking up %s", name);
- fake = getenv("SOCKS5_FAKEALLHOSTS");
- local = getenv("SOCKS5_LOCALDNSONLY");
- if (!fake && (hp = REAL(gethostbyname)(name)) != NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS gethostbyname: REAL: %s", inet_ntoa(*(struct in_addr *)hp->h_addr));
- hlen = MIN(strlen(hp->h_name)+1, sizeof(my_name));
- strncpy(my_name, hp->h_name, hlen);
- if (hlen == sizeof(my_name)) my_name[hlen-1] = ' ';
- HostentCopy(my_addr_list, my_aliases, hp);
- h.h_name = my_name;
- h.h_aliases = my_aliases;
- h.h_addrtype = hp->h_addrtype;
- h.h_length = hp->h_length;
- h.h_addr_list = (char **)my_addr_list;
- lsInWrapFunction = 0;
- lsInWrapHostname = 0;
- return &h;
- }
- /* If your DNS is the same as the socks server, don't fake a correct */
- /* lookup when you know it won't work... */
- if (local) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS gethostbyname: REAL: Fake not configured");
- lsInWrapFunction = 0;
- lsInWrapHostname = 0;
- return NULL;
- }
- /* Fill in some UNRESOLVED values and let the daemon resolve it */
- if ((i = GetFakeHost(name)) <= 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "SOCKS gethostbyname: Get fake host failed");
- lsInWrapFunction = 0;
- lsInWrapHostname = 0;
- return NULL;
- }
- hlen = MIN(strlen(name)+1, sizeof(my_name));
- strncpy(my_name, name, hlen);
- if (hlen == sizeof(my_name)) my_name[hlen-1] = ' ';
- my_aliases[0] = NULL;
- special_addr.s_addr = htonl(i);
- my_addr_list[0] = &special_addr;
- my_addr_list[1] = NULL;
- h.h_name = my_name;
- h.h_aliases = my_aliases;
- h.h_addrtype = AF_INET;
- h.h_length = sizeof(struct in_addr);
- h.h_addr_list = (char **)my_addr_list;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS gethostbyname: FAKE: %s", inet_ntoa(*(struct in_addr *)h.h_addr_list[0]));
- lsInWrapFunction = 0;
- lsInWrapHostname = 0;
- return &h;
- }
- int lsGetCachedAddress(const char *name, S5NetAddr *na) {
- int i;
- char hostname[S5_HOSTNAME_SIZE];
- if (fd > 0) {
- SetReadLock(1);
- lseek(fd, sizeof(int), SEEK_SET);
- for (i = 1; i < 256; i++) {
- if (REAL(read)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "lsGetCachedAddress: read fake table failed %m");
- SetReadLock(0);
- return -1;
- }
- if (hostname[0] == ' ') {
- SetReadLock(0);
- return -1;
- }
- if (strcasecmp(name, hostname)) continue;
- SetReadLock(0);
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(20), 0, "lsGetCachedAddress: Faked host #%d, name is: %s", i, hostname);
- memset(&na->sin, 0, sizeof(ssi));
- na->sin.sin_family = AF_INET;
- na->sin.sin_port = 0;
- na->sin.sin_addr.s_addr = htonl(i);
- return 0;
- }
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsGetCachedAddress: Not a fake a hostname: %s", name);
- return -1;
- }
- /* checks if the address is an unresolved-address and if so, returns the */
- /* unresolved hostname else returns NULL */
- int lsGetCachedHostname(const S5NetAddr *na, char *hostname, int len) {
- int i;
- if (!na || !hostname) return -1;
- if ((i = (int)ntohl(na->sin.sin_addr.s_addr)) > 255 || i < 1) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(20), 0, "lsGetCachedHostname: Not a fake hostname: %s", inet_ntoa(na->sin.sin_addr));
- return -1;
- }
- if (fd > 0) {
- SetReadLock(1);
- lseek(fd, (i-1)*S5_HOSTNAME_SIZE+sizeof(int), SEEK_SET);
- if (REAL(read)(fd, hostname, len) != len) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "lsGetCachedHostname: read fake table failed %m");
- SetReadLock(0);
- return -1;
- }
- SetReadLock(0);
- if (!*hostname) return -1;
- hostname[len - 1] = ' ';
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(20), 0, "lsGetCachedHostname: Faked host #%d, name is: %s", i, hostname);
- return 0;
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsGetCachedHostname: Not a fake hostname: %s", inet_ntoa(na->sin.sin_addr));
- return -1;
- }