[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r4267 - in GNUnet: . src/include src/server src/transports
From: |
grothoff |
Subject: |
[GNUnet-SVN] r4267 - in GNUnet: . src/include src/server src/transports src/transports/upnp src/util/network |
Date: |
Mon, 8 Jan 2007 20:36:04 -0800 (PST) |
Author: grothoff
Date: 2007-01-08 20:36:00 -0800 (Mon, 08 Jan 2007)
New Revision: 4267
Modified:
GNUnet/ChangeLog
GNUnet/src/include/gnunet_util_network.h
GNUnet/src/server/connection.c
GNUnet/src/transports/ip.c
GNUnet/src/transports/upnp/ip.c
GNUnet/src/util/network/Makefile.am
Log:
fixing performance issues
Modified: GNUnet/ChangeLog
===================================================================
--- GNUnet/ChangeLog 2007-01-09 04:15:50 UTC (rev 4266)
+++ GNUnet/ChangeLog 2007-01-09 04:36:00 UTC (rev 4267)
@@ -1,3 +1,9 @@
+Mon Jan 8 21:34:02 MST 2007
+ Forcing -O3 for crypto library (performance critical).
+ Enforcing message queue limit for daemon (somehow got lost
+ on the way to 0.7.1, was responsible for high CPU load).
+ Fixing cron job deletion in core (clean shutdown).
+
Sun Dec 31 23:56:31 MST 2006
ncurses may need "-lm" in order to link.
Releasing GNUnet 0.7.1a.
Modified: GNUnet/src/include/gnunet_util_network.h
===================================================================
--- GNUnet/src/include/gnunet_util_network.h 2007-01-09 04:15:50 UTC (rev
4266)
+++ GNUnet/src/include/gnunet_util_network.h 2007-01-09 04:36:00 UTC (rev
4267)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other
contributing authors)
+ (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and
other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -479,6 +479,17 @@
int select_disconnect(struct SelectHandle * sh,
struct SocketHandle * sock);
+
+/**
+ * Get the IP address for the local machine.
+ * @return NULL on error, IP as string otherwise
+ */
+char * network_get_local_ip(struct GC_Configuration * cfg,
+ struct GE_Context * ectx,
+ IPaddr * addr);
+
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
Modified: GNUnet/src/server/connection.c
===================================================================
--- GNUnet/src/server/connection.c 2007-01-09 04:15:50 UTC (rev 4266)
+++ GNUnet/src/server/connection.c 2007-01-09 04:36:00 UTC (rev 4267)
@@ -602,6 +602,8 @@
static int stat_total_allowed_recv;
+static int stat_total_send_buffer_size;
+
/* ******************** CODE ********************* */
#if DEBUG_CONNECTION
@@ -1080,8 +1082,7 @@
get_time(),
priority);
#endif
- }
- else {
+ } else {
(*priority) = solveKnapsack(be,
be->session.mtu -
sizeof(P2P_PACKET_HEADER));
@@ -1092,8 +1093,7 @@
priority);
#endif
}
- }
- else { /* never approximate < 50% CPU load */
+ } else { /* never approximate < 50% CPU load */
(*priority) = solveKnapsack(be,
be->session.mtu -
sizeof(P2P_PACKET_HEADER));
@@ -1105,10 +1105,11 @@
#endif
}
j = 0;
- for(i = 0; i < be->sendBufferSize; i++)
- if(be->sendBuffer[i]->knapsackSolution == YES)
+ for (i = 0; i < be->sendBufferSize; i++)
+ if (be->sendBuffer[i]->knapsackSolution == YES)
j++;
if (j == 0) {
+ GE_BREAK(ectx, 0);
GE_LOG(ectx,
GE_ERROR | GE_BULK | GE_DEVELOPER,
_("`%s' selected %d out of %d messages (MTU: %d).\n"),
@@ -1117,7 +1118,7 @@
be->sendBufferSize,
be->session.mtu - sizeof(P2P_PACKET_HEADER));
- for(j = 0; j < be->sendBufferSize; j++)
+ for (j = 0; j < be->sendBufferSize; j++)
GE_LOG(ectx,
GE_ERROR | GE_BULK | GE_DEVELOPER,
_("Message details: %u: length %d, priority: %d\n"),
@@ -1171,12 +1172,14 @@
load = os_cpu_get_load(ectx, cfg);
if (load < 0)
- load = 50; /* failed to determine load, assume 50%* */
- /* cleanup queue */
- msgCap = be->max_bpm; /* have minute of msgs, but at least one MTU */
- if(msgCap < EXPECTED_MTU)
- msgCap = EXPECTED_MTU;
- if (load < 50) { /* afford more if CPU load is low */
+ load = 50; /* failed to determine load, assume 50% */
+ /* cleanup queue: keep enough buffer for one minute */
+ msgCap = be->max_bpm; /* have minute of msgs */
+ if (msgCap < EXPECTED_MTU)
+ msgCap = EXPECTED_MTU; /* have at least one MTU */
+ if (msgCap > max_bpm_up)
+ msgCap = max_bpm_up; /* have no more than max-bpm for entire daemon */
+ if (load < 50) { /* afford more if CPU load is low */
if (load == 0)
load = 1; /* avoid division by zero */
msgCap += (MAX_SEND_BUFFER_SIZE - EXPECTED_MTU) / load;
@@ -1184,15 +1187,13 @@
usedBytes = 0;
/* allow at least msgCap bytes in buffer */
- for(i = 0; i < be->sendBufferSize; i++)
- if(be->sendBuffer[i] != NULL)
- usedBytes += be->sendBuffer[i]->len;
-
- for(i = 0; i < be->sendBufferSize; i++) {
+ for (i = 0; i < be->sendBufferSize; i++) {
entry = be->sendBuffer[i];
- if(entry == NULL)
+ if (entry == NULL)
continue;
- if(entry->transmissionTime <= expired) {
+
+ if ( (entry->transmissionTime <= expired) ||
+ (usedBytes > msgCap) ) {
#if DEBUG_CONNECTION
GE_LOG(ectx,
GE_DEBUG | GE_REQUEST | GE_USER,
@@ -1205,18 +1206,20 @@
stats->change(stat_sizeMessagesDropped, entry->len);
}
FREENONNULL(entry->closure);
- usedBytes -= entry->len;
FREE(entry);
be->sendBuffer[i] = NULL;
}
+ usedBytes += entry->len;
}
/* cleanup/compact sendBuffer */
j = 0;
for(i = 0; i < be->sendBufferSize; i++)
- if(be->sendBuffer[i] != NULL)
+ if (be->sendBuffer[i] != NULL)
be->sendBuffer[j++] = be->sendBuffer[i];
- GROW(be->sendBuffer, be->sendBufferSize, j);
+ GROW(be->sendBuffer,
+ be->sendBufferSize,
+ j);
}
/**
@@ -1237,7 +1240,7 @@
SendEntry *entry;
ret = 0;
- for(i = 0; i < be->sendBufferSize; i++) {
+ for (i = 0; i < be->sendBufferSize; i++) {
entry = be->sendBuffer[i];
if(entry->knapsackSolution == YES) {
@@ -1255,8 +1258,7 @@
FREE(entry);
be->sendBuffer[i] = NULL;
}
- }
- else {
+ } else {
ret++;
}
#if 0
@@ -1297,10 +1299,10 @@
perm = permute(WEAK, be->sendBufferSize);
headpos = 0;
tailpos = be->sendBufferSize - 1;
- for(i = 0; i < be->sendBufferSize; i++) {
- if(be->sendBuffer[perm[i]] == NULL)
+ for (i = 0; i < be->sendBufferSize; i++) {
+ if (be->sendBuffer[perm[i]] == NULL)
continue;
- if(be->sendBuffer[perm[i]]->knapsackSolution == YES) {
+ if (be->sendBuffer[perm[i]]->knapsackSolution == YES) {
switch (be->sendBuffer[perm[i]]->flags & SE_PLACEMENT_FLAG) {
case SE_FLAG_NONE:
break;
@@ -1330,7 +1332,7 @@
int i;
SendEntry *entry;
- for(i = 0; i < be->sendBufferSize; i++) {
+ for (i = 0; i < be->sendBufferSize; i++) {
entry = be->sendBuffer[i];
GE_ASSERT(ectx, entry != NULL);
if(entry->knapsackSolution == YES) {
@@ -1338,8 +1340,8 @@
FREENONNULL(entry->closure);
FREE(entry);
be->sendBuffer[i] = NULL;
- }
- else if((entry->callback == NULL) && (entry->closure == NULL)) {
+ } else if ( (entry->callback == NULL) &&
+ (entry->closure == NULL) ) {
FREE(entry);
be->sendBuffer[i] = NULL;
}
@@ -1514,7 +1516,7 @@
p2pHdr->bandwidth = htonl(be->idealized_limit);
p = sizeof(P2P_PACKET_HEADER);
- for(i = 0; i < be->sendBufferSize; i++) {
+ for (i = 0; i < be->sendBufferSize; i++) {
SendEntry *entry = be->sendBuffer[perm[i]];
if(entry == NULL)
@@ -1529,7 +1531,9 @@
#endif
GE_ASSERT(ectx, entry->callback == NULL);
GE_ASSERT(ectx, p + entry->len <= totalMessageSize);
- memcpy(&plaintextMsg[p], entry->closure, entry->len);
+ memcpy(&plaintextMsg[p],
+ entry->closure,
+ entry->len);
p += entry->len;
}
}
@@ -1708,7 +1712,7 @@
return;
}
queueSize = 0;
- for(i = 0; i < be->sendBufferSize; i++)
+ for (i = 0; i < be->sendBufferSize; i++)
queueSize += be->sendBuffer[i]->len;
if (queueSize >= MAX_SEND_BUFFER_SIZE) {
@@ -2377,6 +2381,15 @@
/* ******** end of inbound bandwidth scheduling ************* */
+/**
+ * note: should we see that this cron job takes excessive amounts of
+ * CPU on some systems, we may consider adding an OPTION to reduce the
+ * frequency. However, on my system, larger values significantly
+ * impact the performance of the UDP transport for large (fragmented)
+ * messages -- and 10ms does not cause any noticeable CPU load during
+ * testing.
+ */
+#define CDL_FREQUENCY (10 * cronMILLIS)
/**
* Call this method periodically to drop dead connections.
@@ -2391,16 +2404,19 @@
int i;
unsigned long long total_allowed_sent;
unsigned long long total_allowed_recv;
-
+ unsigned long long total_send_buffer_size;
+
scheduleInboundTraffic();
now = get_time();
total_allowed_sent = 0;
total_allowed_recv = 0;
+ total_send_buffer_size = 0;
MUTEX_LOCK(lock);
for (i = 0; i < CONNECTION_MAX_HOSTS_; i++) {
root = CONNECTION_buffer_[i];
prev = NULL;
while (NULL != root) {
+ total_send_buffer_size += root->sendBufferSize;
switch (root->status) {
case STAT_DOWN:
/* just compact linked list */
@@ -2498,6 +2514,8 @@
total_allowed_sent / 60); /* bpm to bps */
stats->set(stat_total_allowed_recv,
total_allowed_recv / 60); /* bpm to bps */
+ stats->set(stat_total_send_buffer_size,
+ total_send_buffer_size);
}
}
@@ -3037,18 +3055,10 @@
GE_ASSERT(ectx,
CONNECTION_MAX_HOSTS_ != 0);
registerp2pHandler(P2P_PROTO_hangup, &handleHANGUP);
- /* note: should we see that this cron job takes
- excessive amounts of CPU on some systems, we
- may consider adding an OPTION to reduce the
- frequency. However, on my system, larger
- values significantly impact the performance
- of the UDP transport for large (fragmented)
- messages -- and 10ms does not cause any noticeable
- CPU load during testing. */
cron_add_job(cron,
&cronDecreaseLiveness,
- 10 * cronMILLIS,
- 10 * cronMILLIS,
+ CDL_FREQUENCY,
+ CDL_FREQUENCY,
NULL);
#if DEBUG_COLLECT_PRIO == YES
prioFile = FOPEN("/tmp/knapsack_prio.txt", "w");
@@ -3096,6 +3106,8 @@
= stats->create(gettext_noop("# total advertised bytes per second
received limit"));
stat_total_allowed_recv
= stats->create(gettext_noop("# total allowed bytes per second
transmission limit"));
+ stat_total_send_buffer_size
+ = stats->create(gettext_noop("# total number of messages in send
buffers"));
}
transport->start(&core_receive);
}
@@ -3115,7 +3127,7 @@
NULL);
cron_del_job(cron,
&cronDecreaseLiveness,
- 1 * cronSECONDS,
+ CDL_FREQUENCY,
NULL);
for(i = 0; i < CONNECTION_MAX_HOSTS_; i++) {
BufferEntry *prev;
@@ -3214,20 +3226,21 @@
ttype = 0;
if(tmp->session.tsession != NULL)
ttype = tmp->session.tsession->ttype;
- GE_LOG(ectx, GE_INFO | GE_REQUEST | GE_USER,
- "CONNECTION-TABLE: %3d-%1d-%2d-%4ds"
- " (of %ds) BPM %4llu %8ut-%3u: %s-%s-%s\n",
- i,
- tmp->status,
- ttype,
- (int) ((get_time() - tmp->isAlive) / cronSECONDS),
- SECONDS_INACTIVE_DROP,
- tmp->recently_received,
- tmp->idealized_limit,
- tmp->sendBufferSize,
- &hostName,
- &skey_local,
- &skey_remote);
+ GE_LOG(ectx,
+ GE_INFO | GE_REQUEST | GE_USER,
+ "CONNECTION-TABLE: %3d-%1d-%2d-%4ds"
+ " (of %ds) BPM %4llu %8ut-%3u: %s-%s-%s\n",
+ i,
+ tmp->status,
+ ttype,
+ (int) ((get_time() - tmp->isAlive) / cronSECONDS),
+ SECONDS_INACTIVE_DROP,
+ tmp->recently_received,
+ tmp->idealized_limit,
+ tmp->sendBufferSize,
+ &hostName,
+ &skey_local,
+ &skey_remote);
}
tmp = tmp->overflowChain;
}
Modified: GNUnet/src/transports/ip.c
===================================================================
--- GNUnet/src/transports/ip.c 2007-01-09 04:15:50 UTC (rev 4266)
+++ GNUnet/src/transports/ip.c 2007-01-09 04:36:00 UTC (rev 4267)
@@ -22,17 +22,6 @@
* @file transports/ip.c
* @brief code to determine the IP of the local machine
*
- *
- * Determine the IP of the local machine. We have many
- * ways to get that IP:
- * a) from the interface (ifconfig)
- * b) via DNS from our HOSTNAME (environment)
- * c) from the configuration (HOSTNAME specification or static IP)
- *
- * Which way applies depends on the OS, the configuration
- * (dynDNS? static IP? NAT?) and at the end what the user
- * needs.
- *
* @author Christian Grothoff
* @author Tzvetan Horozov
* @author Heikki Lindholm
@@ -43,362 +32,10 @@
#include "gnunet_util.h"
#include "ip.h"
-/* maximum length of hostname */
-#define MAX_HOSTNAME 1024
-
/**
- * Obtain the identity information for the current node
- * (connection information), conInfo.
- * @return SYSERR on failure, OK on success
- */
-static int getAddressFromHostname(struct GE_Context * ectx,
- IPaddr * identity) {
- char hostname[MAX_HOSTNAME];
- int ret;
-
- if (0 != gethostname(hostname, MAX_HOSTNAME)) {
- GE_LOG_STRERROR(ectx,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
- "gethostname");
- return SYSERR;
- }
- ret = get_host_by_name(ectx,
- hostname,
- identity);
- return ret;
-}
-
-#if HAVE_GETIFADDRS && HAVE_FREEIFADDRS
-static int getAddressFromGetIfAddrs(struct GC_Configuration * cfg,
- struct GE_Context * ectx,
- IPaddr * identity) {
- char * interfaces;
- struct ifaddrs *ifa_first;
-
- if (-1 == GC_get_configuration_value_string(cfg,
- "NETWORK",
- "INTERFACE",
- "eth0",
- &interfaces)) {
- GE_LOG(ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("No interface specified in section `%s' under `%s'!\n"),
- "NETWORK",
- "INTERFACE");
- return SYSERR; /* that won't work! */
- }
-
- if (getifaddrs(&ifa_first) == 0) {
- struct ifaddrs *ifa_ptr;
-
- ifa_ptr = ifa_first;
- for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next) {
- if (ifa_ptr->ifa_name != NULL &&
- ifa_ptr->ifa_addr != NULL &&
- (ifa_ptr->ifa_flags & IFF_UP) != 0) {
- if (strcmp(interfaces, (char *)ifa_ptr->ifa_name) != 0)
- continue;
- if (ifa_ptr->ifa_addr->sa_family != AF_INET)
- continue;
- memcpy(identity,
- &(((struct sockaddr_in *)ifa_ptr->ifa_addr)->sin_addr),
- sizeof(struct in_addr));
- freeifaddrs(ifa_first);
- FREE(interfaces);
- return OK;
- }
- }
- freeifaddrs(ifa_first);
- }
- GE_LOG(ectx,
- GE_WARNING | GE_USER | GE_BULK,
- _("Could not obtain IP for interface `%s' using `%s'.\n"),
- interfaces,
- "getifaddrs");
- FREE(interfaces);
- return SYSERR;
-}
-#endif
-
-#if LINUX || SOMEBSD || MINGW
-#define MAX_INTERFACES 16
-static int getAddressFromIOCTL(struct GC_Configuration * cfg,
- struct GE_Context * ectx,
- IPaddr * identity) {
- char * interfaces;
-#ifndef MINGW
- struct ifreq ifr[MAX_INTERFACES];
- struct ifconf ifc;
- int sockfd,ifCount;
-#else
- DWORD dwIP;
-#endif
- int i;
-
- if (-1 == GC_get_configuration_value_string(cfg,
- "NETWORK",
- "INTERFACE",
- "eth0",
- &interfaces)) {
- GE_LOG(ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("No interface specified in section `%s' under `%s'!\n"),
- "NETWORK",
- "INTERFACE");
- return SYSERR; /* that won't work! */
- }
-#ifndef MINGW
- sockfd = SOCKET(PF_INET, SOCK_DGRAM, 0);
- if (sockfd == -1) {
- FREE(interfaces);
- GE_LOG_STRERROR(ectx,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
- "socket");
- return SYSERR;
- }
- memset(&ifc,
- 0,
- sizeof(struct ifconf));
- ifc.ifc_len = sizeof(ifr);
- ifc.ifc_buf = (char*)𝔦
-
- if (ioctl(sockfd,
- SIOCGIFCONF,
- &ifc) == -1) {
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_USER | GE_BULK,
- "ioctl");
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- FREE(interfaces);
- return SYSERR;
- }
- ifCount = ifc.ifc_len / sizeof(struct ifreq);
-
- /* first, try to find exatly matching interface */
- for (i=0;i<ifCount;i++){
- if (ioctl(sockfd, SIOCGIFADDR, &ifr[i]) != 0)
- continue;
- if (ioctl(sockfd, SIOCGIFFLAGS, &ifr[i]) != 0)
- continue;
- if (!(ifr[i].ifr_flags & IFF_UP))
- continue;
- if (strcmp((char*) interfaces,
- (char*) ifr[i].ifr_name) != 0)
- continue;
- memcpy(identity,
- &(((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr),
- sizeof(struct in_addr));
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- FREE(interfaces);
- return OK;
- }
- GE_LOG(ectx,
- GE_WARNING | GE_ADMIN | GE_USER | GE_BULK,
- _("Could not find interface `%s' using `%s', "
- "trying to find another interface.\n"),
- interfaces,
- "ioctl");
- /* if no such interface exists, take any interface but loopback */
- for (i=0;i<ifCount;i++){
- if (ioctl(sockfd, SIOCGIFADDR, &ifr[i]) != 0)
- continue;
- if (ioctl(sockfd, SIOCGIFFLAGS, &ifr[i]) != 0)
- continue;
- if (!(ifr[i].ifr_flags & IFF_UP))
- continue;
- if (strncmp("lo",
- (char*) ifr[i].ifr_name, 2) == 0)
- continue;
- memcpy(identity,
- &(((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr),
- sizeof(struct in_addr));
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- FREE(interfaces);
- return OK;
- }
-
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- GE_LOG(ectx,
- GE_WARNING | GE_USER | GE_BULK,
- _("Could not obtain IP for interface `%s' using `%s'.\n"),
- interfaces,
- "ioctl");
- FREE(interfaces);
- return SYSERR;
-#else /* MinGW */
-
- /* Win 98 or Win NT SP 4 */
- if (GNGetIpAddrTable)
- {
- PMIB_IFTABLE pTable;
- PMIB_IPADDRTABLE pAddrTable;
- DWORD dwIfIdx;
- unsigned int iAddrCount = 0;
-
- dwIP = 0;
-
- EnumNICs(&pTable, &pAddrTable);
-
- for(dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
- unsigned long long l;
- BYTE bPhysAddr[MAXLEN_PHYSADDR];
-
- l = _atoi64(interfaces);
-
- memset(bPhysAddr, 0, MAXLEN_PHYSADDR);
- memcpy(bPhysAddr,
- pTable->table[dwIfIdx].bPhysAddr,
- pTable->table[dwIfIdx].dwPhysAddrLen);
-
- if (memcmp(bPhysAddr, &l, sizeof(l)) == 0) {
- for(i = 0; i < pAddrTable->dwNumEntries; i++) {
- if (pAddrTable->table[i].dwIndex
- == pTable->table[dwIfIdx].dwIndex) {
- iAddrCount++;
- dwIP = pAddrTable->table[i].dwAddr;
- }
- }
- }
- }
-
- if (! iAddrCount)
- {
- GE_LOG(ectx, GE_WARNING | GE_BULK | GE_USER,
- _("Could not find an IP address for "
- "interface `%s'.\n"),
- interfaces);
-
- GlobalFree(pTable);
- GlobalFree(pAddrTable);
- return SYSERR;
- }
- else if (iAddrCount > 1)
- GE_LOG(ectx, GE_WARNING | GE_BULK | GE_USER,
- _("There is more than one IP address specified"
- " for interface `%s'.\nGNUnet will "
- "use %u.%u.%u.%u.\n"),
- interfaces,
- PRIP(ntohl(dwIP)));
-
- identity->addr = dwIP;
-
- GlobalFree(pTable);
- GlobalFree(pAddrTable);
- }
- else /* Win 95 */
- {
- SOCKET s;
- HOSTENT *pHost;
- SOCKADDR_IN theHost;
-
- s = SOCKET(PF_INET, SOCK_STREAM, 0);
- pHost = GETHOSTBYNAME("www.example.com");
- if (! pHost) {
- GE_LOG(ectx, GE_ERROR | GE_BULK | GE_USER,
- _("Could not resolve `%s' to "
- "determine our IP address: %s\n"),
- "www.example.com",
- STRERROR(errno));
- return SYSERR;
- }
-
- theHost.sin_family = AF_INET;
- theHost.sin_port = htons(80);
- theHost.sin_addr.S_un.S_addr
- = *((unsigned long *) pHost->h_addr_list[0]);
- if (CONNECT(s,
- (SOCKADDR *) &theHost,
- sizeof(theHost)) == SOCKET_ERROR) {
- GE_LOG_STRERROR(ectx, GE_ERROR | GE_BULK | GE_USER,
- "connect");
- return SYSERR;
- }
-
- i = sizeof(theHost);
- if (GETSOCKNAME(s,
- (SOCKADDR *) &theHost,
- &i) == SOCKET_ERROR) {
- GE_LOG_STRERROR(ectx, GE_ERROR | GE_BULK | GE_USER,
- "getsockname");
- return SYSERR;
- }
- closesocket(s);
- identity->addr = theHost.sin_addr.S_un.S_addr;
- }
-
- GE_LOG(ectx, GE_DEBUG | GE_REQUEST | GE_USER,
- _("GNUnet now uses the IP address %u.%u.%u.%u.\n"),
- PRIP(ntohl(identity->addr)));
-
- return OK;
-#endif
-}
-
-#endif
-
-/**
* Get the IP address for the local machine.
* @return SYSERR on error, OK on success
*/
-static int getAddress(struct GC_Configuration * cfg,
- struct GE_Context * ectx,
- IPaddr * address){
- char * ipString;
- int retval;
-
- retval = SYSERR;
- if (GC_have_configuration_value(cfg,
- "NETWORK",
- "IP")) {
- ipString = NULL;
- GC_get_configuration_value_string(cfg,
- "NETWORK",
- "IP",
- "",
- &ipString);
- if (strlen(ipString) > 0) {
- retval = get_host_by_name(ectx,
- ipString,
- address);
- }
- FREE(ipString);
- }
-#if LINUX || SOMEBSD || MINGW
- if (retval == SYSERR)
- if (OK == getAddressFromIOCTL(cfg,
- ectx,
- address))
- retval = OK;
-#endif
-#if HAVE_GETIFADDRS && HAVE_FREEIFADDRS
- if (retval == SYSERR)
- if (OK == getAddressFromGetIfAddrs(cfg,
- ectx,
- address))
- retval = OK;
-#endif
- if (retval == SYSERR)
- retval = getAddressFromHostname(ectx,
- address);
- return retval;
-}
-
-/**
- * Get the IP address for the local machine.
- * @return SYSERR on error, OK on success
- */
int getPublicIPAddress(struct GC_Configuration * cfg,
struct GE_Context * ectx,
IPaddr * address) {
@@ -406,14 +43,16 @@
static cron_t last;
static cron_t lastError;
cron_t now;
+ char * ips;
now = get_time();
if (last + cronMINUTES < now) {
if (lastError + 30 * cronSECONDS > now)
return SYSERR;
- if (SYSERR == getAddress(cfg,
- ectx,
- &myAddress)) {
+ ips = network_get_local_ip(cfg,
+ ectx,
+ &myAddress);
+ if (ips == NULL) {
GE_LOG(ectx,
GE_WARNING | GE_USER | GE_BULK,
_("Failed to obtain my (external) %s address!\n"),
@@ -421,6 +60,7 @@
lastError = now;
return SYSERR;
}
+ FREE(ips);
last = now;
}
memcpy(address,
Modified: GNUnet/src/transports/upnp/ip.c
===================================================================
--- GNUnet/src/transports/upnp/ip.c 2007-01-09 04:15:50 UTC (rev 4266)
+++ GNUnet/src/transports/upnp/ip.c 2007-01-09 04:36:00 UTC (rev 4267)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2004, 2005, 2006 Christian Grothoff (and other
contributing authors)
+ (C) 2006, 2007 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -22,383 +22,25 @@
* @file transports/upnp/ip.c
* @brief code to determine the IP of the local machine
*
- *
- * Determine the IP of the local machine. We have many
- * ways to get that IP:
- * a) from the interface (ifconfig)
- * b) via DNS from our HOSTNAME (environment)
- * c) from the configuration (HOSTNAME specification or static IP)
- *
- * Which way applies depends on the OS, the configuration
- * (dynDNS? static IP? NAT?) and at the end what the user
- * needs.
- *
* @author Christian Grothoff
- * @author Tzvetan Horozov
*/
#include <stdlib.h>
#include "platform.h"
#include "gnunet_util.h"
#include "ip.h"
-/* maximum length of hostname */
-#define MAX_HOSTNAME 1024
/**
- * Obtain the identity information for the current node
- * (connection information), conInfo.
- * @return SYSERR on failure, OK on success
- */
-static int getAddressFromHostname(struct GE_Context * ectx,
- IPaddr * identity) {
- char hostname[MAX_HOSTNAME];
- int ret;
-
- if (0 != gethostname(hostname, MAX_HOSTNAME)) {
- GE_LOG_STRERROR(ectx,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
- "gethostname");
- return SYSERR;
- }
- ret = get_host_by_name(ectx,
- hostname,
- identity);
- return ret;
-}
-
-#if HAVE_GETIFADDRS && HAVE_FREEIFADDRS
-static int getAddressFromGetIfAddrs(struct GC_Configuration * cfg,
- struct GE_Context * ectx,
- IPaddr * identity) {
- char * interfaces;
- struct ifaddrs *ifa_first;
-
- if (-1 == GC_get_configuration_value_string(cfg,
- "NETWORK",
- "INTERFACE",
- "eth0",
- &interfaces)) {
- GE_LOG(ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("No interface specified in section `%s' under `%s'!\n"),
- "NETWORK",
- "INTERFACE");
- return SYSERR; /* that won't work! */
- }
-
- if (getifaddrs(&ifa_first) == 0) {
- struct ifaddrs *ifa_ptr;
-
- ifa_ptr = ifa_first;
- for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next) {
- if (ifa_ptr->ifa_name != NULL &&
- ifa_ptr->ifa_addr != NULL &&
- (ifa_ptr->ifa_flags & IFF_UP) != 0) {
- if (strcmp(interfaces, (char *)ifa_ptr->ifa_name) != 0)
- continue;
- if (ifa_ptr->ifa_addr->sa_family != AF_INET)
- continue;
- memcpy(identity,
- &(((struct sockaddr_in *)ifa_ptr->ifa_addr)->sin_addr),
- sizeof(struct in_addr));
- freeifaddrs(ifa_first);
- FREE(interfaces);
- return OK;
- }
- }
- freeifaddrs(ifa_first);
- }
- GE_LOG(ectx,
- GE_WARNING | GE_USER | GE_BULK,
- _("Could not obtain IP for interface `%s' using `%s'.\n"),
- interfaces,
- "getifaddrs");
- FREE(interfaces);
- return SYSERR;
-}
-#endif
-
-
-#if LINUX || SOMEBSD || MINGW
-#define MAX_INTERFACES 16
-static int getAddressFromIOCTL(struct GC_Configuration * cfg,
- struct GE_Context * ectx,
- IPaddr * identity) {
- char * interfaces;
-#ifndef MINGW
- struct ifreq ifr[MAX_INTERFACES];
- struct ifconf ifc;
- int sockfd,ifCount;
-#else
- DWORD dwIP;
-#endif
- int i;
-
- if (-1 == GC_get_configuration_value_string(cfg,
- "NETWORK",
- "INTERFACE",
- "eth0",
- &interfaces)) {
- GE_LOG(ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("No interface specified in section `%s' under `%s'!\n"),
- "NETWORK",
- "INTERFACE");
- return SYSERR; /* that won't work! */
- }
-#ifndef MINGW
- sockfd = SOCKET(PF_INET, SOCK_DGRAM, 0);
- if (sockfd == -1) {
- FREE(interfaces);
- GE_LOG_STRERROR(ectx,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
- "socket");
- return SYSERR;
- }
- memset(&ifc,
- 0,
- sizeof(struct ifconf));
- ifc.ifc_len = sizeof(ifr);
- ifc.ifc_buf = (char*)𝔦
-
- if (ioctl(sockfd,
- SIOCGIFCONF,
- &ifc) == -1) {
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_USER | GE_BULK,
- "ioctl");
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- FREE(interfaces);
- return SYSERR;
- }
- ifCount = ifc.ifc_len / sizeof(struct ifreq);
-
- /* first, try to find exatly matching interface */
- for (i=0;i<ifCount;i++){
- if (ioctl(sockfd, SIOCGIFADDR, &ifr[i]) != 0)
- continue;
- if (ioctl(sockfd, SIOCGIFFLAGS, &ifr[i]) != 0)
- continue;
- if (!(ifr[i].ifr_flags & IFF_UP))
- continue;
- if (strcmp((char*) interfaces,
- (char*) ifr[i].ifr_name) != 0)
- continue;
- memcpy(identity,
- &(((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr),
- sizeof(struct in_addr));
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- FREE(interfaces);
- return OK;
- }
- GE_LOG(ectx,
- GE_WARNING | GE_ADMIN | GE_USER | GE_BULK,
- _("Could not find interface `%s' using `%s', "
- "trying to find another interface.\n"),
- interfaces,
- "ioctl");
- /* if no such interface exists, take any interface but loopback */
- for (i=0;i<ifCount;i++){
- if (ioctl(sockfd, SIOCGIFADDR, &ifr[i]) != 0)
- continue;
- if (ioctl(sockfd, SIOCGIFFLAGS, &ifr[i]) != 0)
- continue;
- if (!(ifr[i].ifr_flags & IFF_UP))
- continue;
- if (strncmp("lo",
- (char*) ifr[i].ifr_name, 2) == 0)
- continue;
- memcpy(identity,
- &(((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr),
- sizeof(struct in_addr));
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- FREE(interfaces);
- return OK;
- }
-
- if (0 != CLOSE(sockfd))
- GE_LOG_STRERROR(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "close");
- GE_LOG(ectx,
- GE_WARNING | GE_USER | GE_BULK,
- _("Could not obtain IP for interface `%s' using `%s'.\n"),
- interfaces,
- "ioctl");
- FREE(interfaces);
- return SYSERR;
-#else /* MinGW */
-
- /* Win 98 or Win NT SP 4 */
- if (GNGetIpAddrTable)
- {
- PMIB_IFTABLE pTable;
- PMIB_IPADDRTABLE pAddrTable;
- DWORD dwIfIdx;
- unsigned int iAddrCount = 0;
-
- dwIP = 0;
-
- EnumNICs(&pTable, &pAddrTable);
-
- for(dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
- unsigned long long l;
- BYTE bPhysAddr[MAXLEN_PHYSADDR];
-
- l = _atoi64(interfaces);
-
- memset(bPhysAddr, 0, MAXLEN_PHYSADDR);
- memcpy(bPhysAddr,
- pTable->table[dwIfIdx].bPhysAddr,
- pTable->table[dwIfIdx].dwPhysAddrLen);
-
- if (memcmp(bPhysAddr, &l, sizeof(l)) == 0) {
- for(i = 0; i < pAddrTable->dwNumEntries; i++) {
- if (pAddrTable->table[i].dwIndex
- == pTable->table[dwIfIdx].dwIndex) {
- iAddrCount++;
- dwIP = pAddrTable->table[i].dwAddr;
- }
- }
- }
- }
-
- if (! iAddrCount)
- {
- GE_LOG(ectx, GE_WARNING | GE_BULK | GE_USER,
- _("Could not find an IP address for "
- "interface `%s'.\n"),
- interfaces);
-
- GlobalFree(pTable);
- GlobalFree(pAddrTable);
- return SYSERR;
- }
- else if (iAddrCount > 1)
- GE_LOG(ectx, GE_WARNING | GE_BULK | GE_USER,
- _("There is more than one IP address specified"
- " for interface `%s'.\nGNUnet will "
- "use %u.%u.%u.%u.\n"),
- interfaces,
- PRIP(ntohl(dwIP)));
-
- identity->addr = dwIP;
-
- GlobalFree(pTable);
- GlobalFree(pAddrTable);
- }
- else /* Win 95 */
- {
- SOCKET s;
- HOSTENT *pHost;
- SOCKADDR_IN theHost;
-
- s = SOCKET(PF_INET, SOCK_STREAM, 0);
- pHost = GETHOSTBYNAME("www.example.com");
- if (! pHost) {
- GE_LOG(ectx, GE_ERROR | GE_BULK | GE_USER,
- _("Could not resolve `%s' to "
- "determine our IP address: %s\n"),
- "www.example.com",
- STRERROR(errno));
- return SYSERR;
- }
-
- theHost.sin_family = AF_INET;
- theHost.sin_port = htons(80);
- theHost.sin_addr.S_un.S_addr
- = *((unsigned long *) pHost->h_addr_list[0]);
- if (CONNECT(s,
- (SOCKADDR *) &theHost,
- sizeof(theHost)) == SOCKET_ERROR) {
- GE_LOG_STRERROR(ectx, GE_ERROR | GE_BULK | GE_USER,
- "connect");
- return SYSERR;
- }
-
- i = sizeof(theHost);
- if (GETSOCKNAME(s,
- (SOCKADDR *) &theHost,
- &i) == SOCKET_ERROR) {
- GE_LOG_STRERROR(ectx, GE_ERROR | GE_BULK | GE_USER,
- "getsockname");
- return SYSERR;
- }
- closesocket(s);
- identity->addr = theHost.sin_addr.S_un.S_addr;
- }
-
- GE_LOG(ectx, GE_DEBUG | GE_REQUEST | GE_USER,
- _("GNUnet now uses the IP address %u.%u.%u.%u.\n"),
- PRIP(ntohl(identity->addr)));
-
- return OK;
-#endif
-}
-
-#endif
-
-/**
* Get the IP address for the local machine.
* @return NULL on error
*/
char * gaim_upnp_get_internal_ip(struct GC_Configuration * cfg,
struct GE_Context * ectx) {
IPaddr address;
- char * ipString;
- int retval;
- char buf[65];
- retval = SYSERR;
- if (GC_have_configuration_value(cfg,
- "NETWORK",
- "IP-LOCAL")) {
- ipString = NULL;
- GC_get_configuration_value_string(cfg,
- "NETWORK",
- "IP-LOCAL",
- "",
- &ipString);
- if (strlen(ipString) > 0) {
- retval = get_host_by_name(ectx,
- ipString,
- &address);
- }
- FREE(ipString);
- }
-#if LINUX || SOMEBSD || MINGW
- if (retval == SYSERR)
- if (OK == getAddressFromIOCTL(cfg,
- ectx,
- &address))
- retval = OK;
-#endif
-#if HAVE_GETIFADDRS && HAVE_FREEIFADDRS
- if (retval == SYSERR)
- if (OK == getAddressFromGetIfAddrs(cfg,
- ectx,
- &address))
- retval = OK;
-#endif
- if (retval == SYSERR)
- retval = getAddressFromHostname(ectx,
- &address);
- if (retval == SYSERR)
- return NULL;
- SNPRINTF(buf,
- 64,
- "%u.%u.%u.%u",
- PRIP(ntohl(*(int*)&address)));
- return STRDUP(buf);
+ return network_get_local_ip(cfg,
+ ectx,
+ &address);
}
Modified: GNUnet/src/util/network/Makefile.am
===================================================================
--- GNUnet/src/util/network/Makefile.am 2007-01-09 04:15:50 UTC (rev 4266)
+++ GNUnet/src/util/network/Makefile.am 2007-01-09 04:36:00 UTC (rev 4267)
@@ -8,6 +8,7 @@
libnetwork_la_SOURCES = \
endian.c network.h \
io.c \
+ ip.c \
ipcheck.c \
select.c
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r4267 - in GNUnet: . src/include src/server src/transports src/transports/upnp src/util/network,
grothoff <=