updates.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 8 Jul 2001 21:26:13 +0000 (21:26 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 8 Jul 2001 21:26:13 +0000 (21:26 +0000)
CHANGES
lib/silcutil/silcnet.c
lib/silcutil/silcsockconn.c
lib/silcutil/silcsockconn.h

diff --git a/CHANGES b/CHANGES
index 713f6333efe30a2cf1cc63eb8b4d7ab5fe15c229..7efbdc0c3c44ca1830c73a825d66331190b8881a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+Mon Jul  9 00:24:45 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added new function silc_socket_host_lookup to perform
+         asynchronous IP and FQDN lookups for the socket connection.
+         Affected files lib/silcutil/silcsockconn.[ch].
+
 Sun Jul  8 18:44:53 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Added SILC_MUTEX_DEFINE to define the mutex on environments
index d92d80a69d70da8a500874c68579693ba557cf25..ad563705080917ae9b8ca103346e4fb6df26e2ef 100644 (file)
@@ -104,7 +104,7 @@ bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
   /* Find the address from list */
   for (i = 0; dest->h_addr_list[i]; i++)
     if (!memcmp(dest->h_addr_list[i], &remote.sin_addr, 
-              sizeof(struct in_addr)))
+               sizeof(struct in_addr)))
       break;
   if (!dest->h_addr_list[i])
     return FALSE;
index afe1b2811263fbdc16f1c23efaf1a505ef853ed4..2d6dfe0b35f6017b9e0870a361bf4cea51716fff 100644 (file)
@@ -31,6 +31,15 @@ struct SilcSocketConnectionHBStruct {
   SilcSocketConnection sock;
 };
 
+/* Internal async host lookup context. */
+typedef struct {
+  SilcSocketHostLookupCb callback;
+  void *context;
+  void *timeout_queue;
+  SilcSocketConnection sock;
+  bool port;
+} *SilcSocketHostLookup;
+
 /* Allocates a new socket connection object. The allocated object is 
    returned to the new_socket argument. */
 
@@ -117,6 +126,9 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock,
                               void *timeout_queue)
 {
 
+  if (!timeout_queue)
+    return;
+
   if (sock->hb) {
     silc_task_unregister(sock->hb->timeout_queue, sock->hb->hb_task);
     silc_free(sock->hb->hb_context);
@@ -135,3 +147,90 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock,
                                          SILC_TASK_TIMEOUT,
                                          SILC_TASK_PRI_LOW);
 }
+
+/* Finishing timeout callback that will actually call the user specified
+   host lookup callback. This is executed back in the calling thread and
+   not in the lookup thread. */
+
+SILC_TASK_CALLBACK(silc_socket_host_lookup_finish)
+{
+  SilcSocketHostLookup lookup = (SilcSocketHostLookup)context;
+
+  SILC_UNSET_HOST_LOOKUP(lookup->sock);
+
+  /* If the reference counter is 1 we know that we are the only one
+     holding the socket and it thus is considered freed. The lookup
+     is cancelled also and we will not call the final callback. */
+  if (lookup->sock->users == 1) {
+    SILC_LOG_DEBUG(("Async host lookup was cancelled"));
+    silc_free(lookup);
+    silc_socket_free(lookup->sock);
+    return;
+  }
+
+  SILC_LOG_DEBUG(("Async host lookup finished"));
+
+  silc_socket_free(lookup->sock);
+
+  /* Call the final callback. */
+  if (lookup->callback)
+    lookup->callback(lookup->sock, lookup->context);
+
+  silc_free(lookup);
+}
+
+/* The thread function that performs the actual lookup. */
+
+static void *silc_socket_host_lookup_start(void *context)
+{
+  SilcSocketHostLookup lookup = (SilcSocketHostLookup)context;
+  SilcSocketConnection sock = lookup->sock;
+
+  if (lookup->port)
+    sock->port = silc_net_get_remote_port(sock->sock);
+
+  silc_net_check_host_by_sock(sock->sock, &sock->hostname, &sock->ip);  
+  if (!sock->hostname && sock->ip)
+    sock->hostname = strdup(sock->ip);
+
+  silc_task_register(lookup->timeout_queue, sock->sock,
+                    silc_socket_host_lookup_finish, lookup, 0, 1,
+                    SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+
+  return NULL;
+}
+
+/* Performs asynchronous host name and IP address lookups for the
+   specified socket connection. This may be called when the socket
+   connection is created and the full IP address and fully qualified
+   domain name information is desired. The `callback' with `context'
+   will be called after the lookup is performed. The `timeout_queue'
+   is the application's scheduler timeout queue which the lookup
+   routine needs. If the socket connection is freed during
+   the lookup the library will automatically cancel the lookup and
+   the `callback' will not be called. */
+
+void silc_socket_host_lookup(SilcSocketConnection sock,
+                            bool port_lookup,
+                            SilcSocketHostLookupCb callback,
+                            void *context,
+                            void *timeout_queue)
+{
+  SilcSocketHostLookup lookup;
+
+  SILC_LOG_DEBUG(("Performing async host lookup"));
+
+  if (!timeout_queue)
+    return;
+
+  lookup = silc_calloc(1, sizeof(*lookup));
+  lookup->sock = silc_socket_dup(sock);        /* Increase reference counter */
+  lookup->callback = callback;
+  lookup->context = context;
+  lookup->timeout_queue = timeout_queue;
+  lookup->port = port_lookup;
+
+  SILC_SET_HOST_LOOKUP(sock);
+
+  silc_thread_create(silc_socket_host_lookup_start, lookup, FALSE);
+}
index 75b1627608b26a94548f612dae84a888b50a9980..658c3acda1755f12565d1b2b7f6360c553bd6091 100644 (file)
@@ -93,28 +93,12 @@ typedef enum {
 /***/
 
 /* Socket flags */
-#define SILC_SF_NONE 0
-#define SILC_SF_INBUF_PENDING 1
-#define SILC_SF_OUTBUF_PENDING 2
-#define SILC_SF_DISCONNECTING 3
-#define SILC_SF_DISCONNECTED 4
-
-/****f* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHBCb
- *
- * SYNOPSIS
- *
- *    typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
- *                                             void *context);
- *
- * DESCRIPTION
- *
- *    Heartbeat callback function. This is the function in the application
- *    that this library will call when it is time to send the keepalive
- *    packet SILC_PACKET_HEARTBEAT.
- *
- ***/
-typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
-                                        void *context);
+#define SILC_SF_NONE             0
+#define SILC_SF_INBUF_PENDING    1
+#define SILC_SF_OUTBUF_PENDING   2
+#define SILC_SF_DISCONNECTING    3
+#define SILC_SF_DISCONNECTED     4
+#define SILC_SF_HOST_LOOKUP      5
 
 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionStruct
  *
@@ -223,16 +207,19 @@ struct SilcSocketConnectionStruct {
 #define SILC_SET_INBUF_PENDING(x) SF_SET((x), SILC_SF_INBUF_PENDING)
 #define SILC_SET_DISCONNECTING(x) SF_SET((x), SILC_SF_DISCONNECTING)
 #define SILC_SET_DISCONNECTED(x) SF_SET((x), SILC_SF_DISCONNECTED)
+#define SILC_SET_HOST_LOOKUP(x) SF_SET((x), SILC_SF_HOST_LOOKUP)
 #define SILC_UNSET_OUTBUF_PENDING(x) SF_UNSET((x), SILC_SF_OUTBUF_PENDING)
 #define SILC_UNSET_INBUF_PENDING(x) SF_UNSET((x), SILC_SF_INBUF_PENDING)
 #define SILC_UNSET_DISCONNECTING(x) SF_UNSET((x), SILC_SF_DISCONNECTING)
 #define SILC_UNSET_DISCONNECTED(x) SF_UNSET((x), SILC_SF_DISCONNECTED)
+#define SILC_UNSET_HOST_LOOKUP(x) SF_UNSET((x), SILC_SF_HOST_LOOKUP)
 
 /* Checking for flags */
 #define SILC_IS_OUTBUF_PENDING(x) SF_IS((x), SILC_SF_OUTBUF_PENDING)
 #define SILC_IS_INBUF_PENDING(x) SF_IS((x), SILC_SF_INBUF_PENDING)
 #define SILC_IS_DISCONNECTING(x) SF_IS((x), SILC_SF_DISCONNECTING)
 #define SILC_IS_DISCONNECTED(x) SF_IS((x), SILC_SF_DISCONNECTED)
+#define SILC_IS_HOST_LOOKUP(x) SF_IS((x), SILC_SF_HOST_LOOKUP)
 
 /* Prototypes */
 
@@ -321,6 +308,23 @@ int silc_socket_read(SilcSocketConnection sock);
  ***/
 int silc_socket_write(SilcSocketConnection sock);
 
+/****f* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHBCb
+ *
+ * SYNOPSIS
+ *
+ *    typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
+ *                                             void *context);
+ *
+ * DESCRIPTION
+ *
+ *    Heartbeat callback function. This is the function in the application
+ *    that this library will call when it is time to send the keepalive
+ *    packet SILC_PACKET_HEARTBEAT.
+ *
+ ***/
+typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
+                                        void *context);
+
 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_set_heartbeat
  *
  * SYNOPSIS
@@ -348,4 +352,55 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock,
                               SilcSocketConnectionHBCb hb_callback,
                               void *timeout_queue);
 
+/****f* silcutil/SilcSocketConnectionAPI/SilcSocketHostLookupCb
+ *
+ * SYNOPSIS
+ *
+ *    typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
+ *                                           void *context);
+ *
+ * DESCRIPTION
+ *
+ *    Asynchronous host lookup callback function that will be called
+ *    when the lookup is performed.
+ *
+ ***/
+typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
+                                      void *context);
+
+/****f* silcutil/SilcSocketConnectionAPI/silc_socket_host_lookup
+ *
+ * SYNOPSIS
+ *
+ *    void silc_socket_host_lookup(SilcSocketConnection sock,
+ *                                 SilcSocketHostLookupCb callback,
+ *                                 void *context,
+ *                                 void *timeout_queue);
+ *
+ * DESCRIPTION
+ *
+ *    Performs asynchronous host name and IP address lookups for the
+ *    specified socket connection. This may be called when the socket
+ *    connection is created and the full IP address and fully qualified
+ *    domain name information is desired. The `callback' with `context'
+ *    will be called after the lookup is performed. The `timeout_queue'
+ *    is the application's scheduler timeout queue which the lookup
+ *    routine needs. If the socket connection is freed during the
+ *    lookup the library will automatically cancel the lookup and
+ *    the `callback' will not be called.
+ *
+ *    If `port_lookup' is TRUE then the remote port of the socket 
+ *    connection is resolved. After the information is resolved they
+ *    are accessible using sock->ip and sock->hostname pointers. Note
+ *    that if the both IP and FQDN could not be resolved the sock->hostname
+ *    includes the IP address of the remote host. The resolved port is 
+ *    available in sock->port.
+ *
+ ***/
+void silc_socket_host_lookup(SilcSocketConnection sock,
+                            bool port_lookup,
+                            SilcSocketHostLookupCb callback,
+                            void *context,
+                            void *timeout_queue);
+
 #endif