summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-04-28 19:35:12 +0000
committerNick Mathewson <nickm@torproject.org>2004-04-28 19:35:12 +0000
commitac622d94dcf5c00ab9264ec234ea6e9e1a2a28f9 (patch)
tree1ab02f2335c4920d65fd518185dd5040903e18f9
parent8cc9001391d010f06553a1576276925bc8fc0667 (diff)
downloadtor-ac622d94dcf5c00ab9264ec234ea6e9e1a2a28f9.tar.gz
tor-ac622d94dcf5c00ab9264ec234ea6e9e1a2a28f9.zip
Workarounds for a couple of pieces of windows strangeness.
svn:r1734
-rw-r--r--src/common/crypto.c3
-rw-r--r--src/common/util.c51
-rw-r--r--src/common/util.h1
-rw-r--r--src/or/dns.c19
-rw-r--r--src/or/routerlist.c5
5 files changed, 63 insertions, 16 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 60775e7e7f..8d8c78a1e3 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -41,6 +41,9 @@
#include "util.h"
#ifdef MS_WINDOWS
+#define WIN32_WINNT 0x400
+#define _WIN32_WINNT 0x400
+#define WIN32_LEAN_AND_MEAN
#include <wincrypt.h>
#endif
diff --git a/src/common/util.c b/src/common/util.c
index fb92681e93..64e3a9b5a4 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -39,6 +39,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -55,6 +58,18 @@
#include <grp.h>
#endif
+#ifdef HAVE_WINSOCK_H
+#define WIN32_WINNT 0x400
+#define _WIN32_WINNT 0x400
+#define WIN32_LEAN_AND_MEAN
+#endif
+#if _MSC_VER > 1300
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#elif defined(_MSC_VER)
+#include <winsock.h>
+#endif
+
/* used by inet_addr, not defined on solaris anywhere!? */
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned long) -1)
@@ -1368,6 +1383,42 @@ int tor_inet_aton(const char *c, struct in_addr* addr)
#endif
}
+/* Similar behavior to Unix gethostbyname: resolve 'name', and set
+ * *addr to the proper IP address, in network byte order. Returns 0
+ * on success, -1 on failure; 1 on transient failure.
+ *
+ * (This function exists because standard windows gethostbyname
+ * doesn't treat raw IP addresses properly.)
+ */
+/* Perhaps eventually this should be replaced by a tor_getaddrinfo or
+ * something.
+ */
+int tor_lookup_hostname(const char *name, uint32_t *addr)
+{
+ struct in_addr iaddr;
+ struct hostent *ent;
+ tor_assert(addr);
+ if (tor_inet_aton(name, &iaddr)) {
+ /* It's an IP. */
+ memcpy(addr, &iaddr.s_addr, 4);
+ return 0;
+ } else {
+ ent = gethostbyname(name);
+ if (ent) {
+ /* break to remind us if we move away from IPv4 */
+ tor_assert(ent->h_length == 4);
+ memcpy(addr, ent->h_addr, 4);
+ return 0;
+ }
+ memset(addr, 0, 4);
+#ifdef MS_WINDOWS
+ return (WSAGetLastError() == WSATRY_AGAIN) ? 1 : -1;
+#else
+ return (h_errno == TRY_AGAIN) ? 1 : -1;
+#endif
+ }
+}
+
/*
Local Variables:
mode:c
diff --git a/src/common/util.h b/src/common/util.h
index b0120e7d37..bd65a0153b 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -212,6 +212,7 @@ int switch_id(char *user, char *group);
struct in_addr;
int tor_inet_aton(const char *cp, struct in_addr *addr);
+int tor_lookup_hostname(const char *name, uint32_t *addr);
/* For stupid historical reasons, windows sockets have an independent set of
* errnos which they use as the fancy strikes them.
diff --git a/src/or/dns.c b/src/or/dns.c
index b49e6dafa9..6d7f36fc8a 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -451,7 +451,6 @@ int dnsworker_main(void *data) {
char address[MAX_ADDRESSLEN];
unsigned char address_len;
char answer[5];
- struct hostent *rent;
int *fdarray = data;
int fd;
@@ -475,21 +474,17 @@ int dnsworker_main(void *data) {
}
address[address_len] = 0; /* null terminate it */
- rent = gethostbyname(address);
- if (!rent) {
- if(h_errno == TRY_AGAIN) { /* transient error -- don't cache it */
+ switch (tor_lookup_hostname(address, (uint32_t*)answer+1)) {
+ case 1:
log_fn(LOG_INFO,"Could not resolve dest addr %s (transient).",address);
answer[0] = DNS_RESOLVE_FAILED_TRANSIENT;
- } else { /* permanent error, can be cached */
+ break;
+ case -1:
log_fn(LOG_INFO,"Could not resolve dest addr %s (permanent).",address);
answer[0] = DNS_RESOLVE_FAILED_PERMANENT;
- }
- memset(answer+1,0,4);
- } else {
- tor_assert(rent->h_length == 4); /* break to remind us if we move away from ipv4 */
- answer[0] = DNS_RESOLVE_SUCCEEDED;
- memcpy(answer+1, rent->h_addr, 4);
- log_fn(LOG_INFO,"Resolved address '%s'.",address);
+ case 0:
+ log_fn(LOG_INFO,"Resolved address '%s'.",address);
+ answer[0] = DNS_RESOLVE_SUCCEEDED;
}
if(write_all(fd, answer, 5, 1) != 5) {
log_fn(LOG_ERR,"writing answer failed. Child exiting.");
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 3c01838dc0..3183820314 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -507,14 +507,11 @@ router_resolve(routerinfo_t *router)
{
struct hostent *rent;
- rent = (struct hostent *)gethostbyname(router->address);
- if (!rent) {
+ if (tor_lookup_hostname(router->address, &router->addr)) {
log_fn(LOG_WARN,"Could not get address for router %s (%s).",
router->address, router->nickname);
return -1;
}
- tor_assert(rent->h_length == 4);
- memcpy(&router->addr, rent->h_addr,rent->h_length);
router->addr = ntohl(router->addr); /* get it back into host order */
return 0;