updates.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 23 Feb 2002 19:02:25 +0000 (19:02 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 23 Feb 2002 19:02:25 +0000 (19:02 +0000)
CHANGES
TODO
configure.in.pre
lib/doc/programming_conv.html
lib/silccore/silcpacket.h
lib/silcutil/silcnet.c
lib/silcutil/silcnet.h
lib/silcutil/silcschedule.c
lib/silcutil/silcschedule.h
lib/silcutil/unix/silcunixnet.c

diff --git a/CHANGES b/CHANGES
index b56ca5078ec278b0cb5e93c4014be7168665bd64..5ab197924c3c86d9491e6ef5c61beb19d14663ec 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,22 @@
+Sat Feb 23 20:31:43 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added `prefer_ipv6' argument to the functions
+         silc_net_gethostbyname[_async].  If it is TRUE it will return
+         IPv6 address over IPv4.  If FALSE IPv4 address is returned
+         even if IPv6 address was found.  Affected files
+         lib/silcutil/silcnet.[ch].
+
+       * Added support silc_net_create_connection[_async] to fallback
+         to IPv4 address if IPv6 address could not be used (like if
+         it doesn't work on a specific system).  Affected file in
+         lib/silcutil/unix/silcunixnet.c.
+
+Sat Feb 23 15:20:30 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added silc_schedule_reinit function to do the enlarging
+         of the max tasks handling capabilities of the scheduler.
+         Affected files lib/silcutil/silcschedule.[ch].
+
 Wed Feb 20 20:41:01 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added automatic extern "C" { ... } for C++ compilers so the
diff --git a/TODO b/TODO
index 7e52a12a5aea3d05ab3ba58e2a2f68676c81b079..0b9927e8f114eca7aaaa2d3623e88ecbf842d36b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -35,6 +35,8 @@ TODO/bugs In SILC Client Library
 TODO/bugs In SILC Server
 ========================
 
+ o Remove old  0.6.x backwards support.
+
  o Configuration file additions:
 
        o Add incoming connection frequency, incoming connection frequency
index c8259d79c3bdd87cde3f0a98d2448fc39e0be17c..795dfdedae07a0ae3142a6d470d72451af6703dd 100644 (file)
@@ -805,6 +805,9 @@ lib/silcske/Makefile
 lib/silcutil/Makefile
 lib/silcutil/unix/Makefile
 lib/silcutil/win32/Makefile
+lib/silcutil/beos/Makefile
+lib/silcutil/os2/Makefile
+lib/silcutil/epoc/Makefile
 lib/silcsftp/Makefile
 lib/silcsftp/tests/Makefile
 doc/example_silcd.conf
index bd15c611063844baaa79688f46e0ffe661af2c55..eee033b35af788b1982f5de3c9b9535cf145f239 100644 (file)
@@ -25,8 +25,9 @@ in the name.  All macros start with the "SILC_" prefix.  Example:
 </tt>
 
 <br />&nbsp;<br />
-Also defines (#define) are always capitalised and include underscores to
-separate words in the name.  Also all defines start with the "SILC_" prefix.
+Also other defines (#define) are always capitalised and include 
+underscores to separate words in the name.  Also all defines start with 
+the "SILC_" prefix.
 
 <br />&nbsp;<br />
 <b>Structures</b>
index 54d6bc16a1a9d58962547b7a2f3fc4b9e0267fab..87eee1408ae2562b4e36696c9af541b4449cdbc4 100644 (file)
@@ -511,7 +511,7 @@ int silc_packet_receive(SilcSocketConnection sock);
  *
  * DESCRIPTION
  *
- *    Processes and decrypts the incmoing data, and calls parser callback
+ *    Processes and decrypts the incoming data, and calls parser callback
  *    for each received packet that will handle the actual packet parsing.
  *    If more than one packet was received this calls the parser multiple
  *    times.  The parser callback will get context SilcPacketParserContext
index d85317b9b95805ce55f22ec308b6d841b39ab039..630f93292d485b5ebc39ef35b21c161f20f7ffd3 100644 (file)
@@ -91,6 +91,7 @@ bool silc_net_is_ip(const char *addr)
 typedef struct {
   SilcNetResolveCallback completion;
   void *context;
+  bool prefer_ipv6;
   SilcSchedule schedule;
   char *input;
   char *result;
@@ -116,7 +117,7 @@ static void *silc_net_gethostbyname_thread(void *context)
   SilcNetResolveContext r = (SilcNetResolveContext)context;
   char tmp[64];
 
-  if (silc_net_gethostbyname(r->input, tmp, sizeof(tmp)))
+  if (silc_net_gethostbyname(r->input, r->prefer_ipv6, tmp, sizeof(tmp)))
     r->result = strdup(tmp);
 
   silc_schedule_task_add(r->schedule, 0, silc_net_resolve_completion, r, 0, 1,
@@ -143,24 +144,45 @@ static void *silc_net_gethostbyaddr_thread(void *context)
 
 /* Resolves IP address for hostname. */
 
-bool silc_net_gethostbyname(const char *name, char *address,
+bool silc_net_gethostbyname(const char *name, bool prefer_ipv6, char *address, 
                            uint32 address_len)
 {
 #ifdef HAVE_IPV6
-  struct addrinfo hints, *ai;
+  struct addrinfo hints, *ai, *tmp, *ip4 = NULL, *ip6 = NULL;
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_socktype = SOCK_STREAM;
   if (getaddrinfo(name, NULL, &hints, &ai))
     return FALSE;
 
-  if (getnameinfo(ai->ai_addr, ai->ai_addrlen, address,
-                 address_len, NULL, 0, NI_NUMERICHOST)) {
+  for (tmp = ai; tmp; tmp = tmp->ai_next) {
+    if (tmp->ai_family == AF_INET6) {
+      ip6 = tmp;
+      if (ip4)
+       break;
+      continue;
+    }
+    if (tmp->ai_family == AF_INET) {
+      ip4 = tmp;
+      if (ip6)
+       break;
+      continue;
+    }
+  }
+
+  tmp = (prefer_ipv6 ? (ip6 ? ip6 : ip4) : (ip4 ? ip4 : ip6));
+  if (!tmp) {
     freeaddrinfo(ai);
     return FALSE;
-  } else {
+  }
+
+  if (getnameinfo(tmp->ai_addr, tmp->ai_addrlen, address,
+                 address_len, NULL, 0, NI_NUMERICHOST)) {
     freeaddrinfo(ai);
+    return FALSE;
   }
+
+  freeaddrinfo(ai);
 #else
   struct hostent *hp;
   struct in_addr ip;
@@ -186,6 +208,7 @@ bool silc_net_gethostbyname(const char *name, char *address,
 /* Resolves IP address for hostname async. */
 
 void silc_net_gethostbyname_async(const char *name, 
+                                 bool prefer_ipv6,
                                  SilcSchedule schedule,
                                  SilcNetResolveCallback completion,
                                  void *context)
@@ -194,6 +217,7 @@ void silc_net_gethostbyname_async(const char *name,
 
   r->completion = completion;
   r->context = context;
+  r->prefer_ipv6 = prefer_ipv6;
   r->schedule = schedule;
   r->input = strdup(name);
 
@@ -453,7 +477,7 @@ char *silc_net_localhost(void)
   if (gethostname(hostname, sizeof(hostname)))
     return NULL;
 
-  if (!silc_net_gethostbyname(hostname, ip_addr, sizeof(ip_addr)))
+  if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr)))
     return strdup(hostname);
 
   silc_net_gethostbyaddr(ip_addr, hostname, sizeof(hostname));
@@ -469,7 +493,7 @@ char *silc_net_localip(void)
   if (gethostname(hostname, sizeof(hostname)))
     return NULL;
 
-  if (!silc_net_gethostbyname(hostname, ip_addr, sizeof(ip_addr)))
+  if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr)))
     return NULL;
 
   return strdup(ip_addr);
index 0e85a1bdecb5e465ff966239f4186178081a6039..3001ff260ea427d25662ec2e63534765475f4527 100644 (file)
@@ -252,18 +252,21 @@ typedef void (*SilcNetResolveCallback)(const char *result, void *context);
  *
  * SYNOPSIS
  *
- *    bool silc_net_gethostbyname(const char *name, char *address
- *                                uint32 address_len);
+ *    bool silc_net_gethostbyname(const char *name, bool prefer_ipv6
+ *                                char *address, uint32 address_len);
  *
  * DESCRIPTION
  *
- *    Resolves the IP address of the hostname indicated by the `host'.
- *    This returns TRUE and the IP address of the host, or FALSE
- *    if the address could not be resolved.  This is synchronous
- *    function and will block the calling process.
+ *    Resolves the IP address of the hostname indicated by the `name'.
+ *    This returns TRUE and the IP address of the host to the `address'
+ *    buffer, or FALSE if the address could not be resolved.  This is
+ *    synchronous function and will block the calling process.  If the
+ *    `prefer_ipv6' is TRUE then this will return IPv6 address if it
+ *    finds.  If FALSE if returns IPv4 address even if it found IPv6
+ *    address also.
  *
  ***/
-bool silc_net_gethostbyname(const char *name, char *address, 
+bool silc_net_gethostbyname(const char *name, bool prefer_ipv6, char *address, 
                            uint32 address_len);
 
 /****f* silcutil/SilcNetAPI/silc_net_gethostbyname_async
@@ -271,6 +274,7 @@ bool silc_net_gethostbyname(const char *name, char *address,
  * SYNOPSIS
  *
  *    void silc_net_gethostbyname_async(const char *name, 
+ *                                      bool prefer_ipv6,
  *                                      SilcSchedule schedule,
  *                                      SilcNetResolveCallback completion,
  *                                      void *context)
@@ -278,12 +282,17 @@ bool silc_net_gethostbyname(const char *name, char *address,
  * DESCRIPTION
  *
  *    Asynchronously resolves the IP address of the hostname indicated
- *    by the `host'.  This function returns immediately, and the
+ *    by the `name'.  This function returns immediately, and the
  *    `completion' callback will be called after the resolving is
  *    completed.
  *
+ *    If the `prefer_ipv6' is TRUE then this will return IPv6 address if it
+ *    finds.  If FALSE if returns IPv4 address even if it found IPv6
+ *    address also.
+ *
  ***/
 void silc_net_gethostbyname_async(const char *name, 
+                                 bool prefer_ipv6,
                                  SilcSchedule schedule,
                                  SilcNetResolveCallback completion,
                                  void *context);
@@ -298,9 +307,9 @@ void silc_net_gethostbyname_async(const char *name,
  * DESCRIPTION
  *
  *    Resolves the hostname for the IP address indicated by the `addr'
- *    This returns TRUE and the resolved hostname, or FALSE on error.
- *    The `addr' may be either IPv4 or IPv6 address.  This is
- *    synchronous function and will block the calling process.
+ *    This returns TRUE and the resolved hostname to the `name' buffer, 
+ *    or FALSE on error. The `addr' may be either IPv4 or IPv6 address.
+ *    This is synchronous function and will block the calling process.
  *
  ***/
 bool silc_net_gethostbyaddr(const char *addr, char *name, uint32 name_len);
index 1672fdffa716eec336194bb3748d8acc296bc15f..4084371e9a76dd11573a7c851aa661ab33d5e23c 100644 (file)
@@ -250,6 +250,20 @@ bool silc_schedule_uninit(SilcSchedule schedule)
   return TRUE;
 }
 
+/* Enlarge the capabilities of the scheduler to handle tasks to `max_tasks'. */
+
+bool silc_schedule_reinit(SilcSchedule schedule, int max_tasks)
+{
+  silc_mutex_lock(schedule->lock);
+  if (schedule->max_fd <= max_tasks)
+    return FALSE;
+  schedule->fd_list = silc_realloc(schedule->fd_list, 
+                                  (sizeof(*schedule->fd_list) * max_tasks));
+  schedule->max_fd = max_tasks;
+  silc_mutex_unlock(schedule->lock);
+  return TRUE;
+}
+
 /* Stops the schedule even if it is not supposed to be stopped yet. 
    After calling this, one should call silc_schedule_uninit (after the 
    silc_schedule has returned). */
index 45a5defa78343ffabc7b527a3ba3d051ad7c01a7..eb0e0fbce1a92b08d1b60423310a494bcc19684c 100644 (file)
@@ -316,6 +316,26 @@ SilcSchedule silc_schedule_init(int max_tasks);
  ***/
 bool silc_schedule_uninit(SilcSchedule schedule);
 
+/****f* silcutil/SilcScheduleAPI/silc_schedule_reinit
+ *
+ * SYNOPSIS
+ *
+ *    SilcSchedule silc_schedule_reinit(int max_tasks);
+ *
+ * DESCRIPTION
+ *
+ *    This function can be called to enlarge the task handling capabilities
+ *    of the scheduler indicated by `schedule'.  The `max_tasks' must be
+ *    larger than what was set in silc_schedule_init function.  This function
+ *    returns FALSE if it cannot reinit the scheduler.  This function does
+ *    not do anything else except ready the scheduler to handle `max_tasks'
+ *    number of tasks after this function returns.  It is safe to call this
+ *    function at any time, and it is guaranteed that existing tasks remain
+ *    as they are in the scheduler.
+ *
+ ***/
+bool silc_schedule_reinit(SilcSchedule schedule, int max_tasks);
+
 /****f* silcutil/SilcScheduleAPI/silc_schedule_stop
  *
  * SYNOPSIS
index d1f6384ce7aa3d7f1158fd3f164694fc7b1e15ea..48b17e16c6a16a1545797b63bf0b9361c4d09360 100644 (file)
@@ -155,11 +155,13 @@ int silc_net_create_connection(const char *local_ip, int port,
   int sock, rval;
   char ip_addr[64];
   SilcSockaddr desthost;
+  bool prefer_ipv6 = TRUE;
 
   SILC_LOG_DEBUG(("Creating connection to host %s port %d", host, port));
 
   /* Do host lookup */
-  if (!silc_net_gethostbyname(host, ip_addr, sizeof(ip_addr))) {
+ retry:
+  if (!silc_net_gethostbyname(host, prefer_ipv6, ip_addr, sizeof(ip_addr))) {
     SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
                    "IP address", host));
     return -1;
@@ -172,6 +174,13 @@ int silc_net_create_connection(const char *local_ip, int port,
   /* Create the connection socket */
   sock = socket(desthost.sin.sin_family, SOCK_STREAM, 0);
   if (sock < 0) {
+    /* If address is IPv6, then fallback to IPv4 and see whether we can do
+       better with that on socket creation. */
+    if (prefer_ipv6 && silc_net_is_ip6(ip_addr)) {
+      prefer_ipv6 = FALSE;
+      goto retry;
+    }
+
     SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
     return -1;
   }
@@ -216,12 +225,14 @@ int silc_net_create_connection_async(const char *local_ip, int port,
   int sock, rval;
   char ip_addr[64];
   SilcSockaddr desthost;
+  bool prefer_ipv6 = TRUE;
 
   SILC_LOG_DEBUG(("Creating connection (async) to host %s port %d", 
                  host, port));
 
   /* Do host lookup */
-  if (!silc_net_gethostbyname(host, ip_addr, sizeof(ip_addr))) {
+ retry:
+  if (!silc_net_gethostbyname(host, prefer_ipv6, ip_addr, sizeof(ip_addr))) {
     SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
                    "IP address", host));
     return -1;
@@ -234,6 +245,13 @@ int silc_net_create_connection_async(const char *local_ip, int port,
   /* Create the connection socket */
   sock = socket(desthost.sin.sin_family, SOCK_STREAM, 0);
   if (sock < 0) {
+    /* If address is IPv6, then fallback to IPv4 and see whether we can do
+       better with that on socket creation. */
+    if (prefer_ipv6 && silc_net_is_ip6(ip_addr)) {
+      prefer_ipv6 = FALSE;
+      goto retry;
+    }
+
     SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
     return -1;
   }