gnunet-svn
[Top][All Lists]
Advanced

[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*)&ifr;
-
-  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*)&ifr;
-
-  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 
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]