Unregister qos tasks when deleting socket.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 18 Oct 2003 11:26:30 +0000 (11:26 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 18 Oct 2003 11:26:30 +0000 (11:26 +0000)
lib/silcutil/silcsockconn.c
lib/silcutil/silcsockconn.h
lib/silcutil/unix/silcunixsockconn.c

index a49422487a0329c1262989edbe2ff790fce95248..4a57a343c5c4b6cb74afabefafbfdf08af7be2c1 100644 (file)
@@ -4,13 +4,12 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2001 Pekka Riikonen
+  Copyright (C) 1997 - 2003 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -40,10 +39,10 @@ typedef struct {
   bool port;
 } *SilcSocketHostLookup;
 
-/* Allocates a new socket connection object. The allocated object is 
+/* Allocates a new socket connection object. The allocated object is
    returned to the new_socket argument. */
 
-void silc_socket_alloc(int sock, SilcSocketType type, void *user_data, 
+void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
                       SilcSocketConnection *new_socket)
 {
   SILC_LOG_DEBUG(("Allocating new socket connection object"));
@@ -75,7 +74,10 @@ void silc_socket_free(SilcSocketConnection sock)
       silc_schedule_task_del(sock->hb->schedule, sock->hb->hb_task);
       silc_free(sock->hb);
     }
-    silc_free(sock->qos);
+    if (sock->qos) {
+      silc_schedule_task_del_by_context(sock->qos->schedule, sock->qos);
+      silc_free(sock->qos);
+    }
     silc_free(sock->ip);
     silc_free(sock->hostname);
 
@@ -110,7 +112,7 @@ SILC_TASK_CALLBACK(silc_socket_heartbeat)
   if (hb->hb_callback)
     hb->hb_callback(hb->sock, hb->hb_context);
 
-  hb->hb_task = silc_schedule_task_add(hb->schedule, hb->sock->sock, 
+  hb->hb_task = silc_schedule_task_add(hb->schedule, hb->sock->sock,
                                       silc_socket_heartbeat,
                                       context, hb->heartbeat, 0,
                                       SILC_TASK_TIMEOUT,
@@ -125,7 +127,7 @@ SILC_TASK_CALLBACK(silc_socket_heartbeat)
    but will be freed automatically when calling silc_socket_free.  The
    `schedule' is the application's scheduler. */
 
-void silc_socket_set_heartbeat(SilcSocketConnection sock, 
+void silc_socket_set_heartbeat(SilcSocketConnection sock,
                               SilcUInt32 heartbeat,
                               void *hb_context,
                               SilcSocketConnectionHBCb hb_callback,
@@ -156,11 +158,11 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock,
    that is read.  It is guaranteed that silc_socket_read never returns
    more that `read_limit_bytes' of data.  If more is read the limit
    will be applied for the reading.  The `limit_sec' and `limit_usec'
-   specifies the limit that is applied if `read_rate' and/or 
+   specifies the limit that is applied if `read_rate' and/or
    `read_limit_bytes' is reached.  The `schedule' is the application's
    scheduler. */
 
-void silc_socket_set_qos(SilcSocketConnection sock, 
+void silc_socket_set_qos(SilcSocketConnection sock,
                         SilcUInt32 read_rate,
                         SilcUInt32 read_limit_bytes,
                         SilcUInt32 limit_sec,
@@ -179,6 +181,7 @@ void silc_socket_set_qos(SilcSocketConnection sock,
   sock->qos->schedule = schedule;
   memset(&sock->qos->next_limit, 0, sizeof(sock->qos->next_limit));
   sock->qos->cur_rate = 0;
+  sock->qos->sock = sock;
 }
 
 /* Finishing timeout callback that will actually call the user specified
@@ -223,7 +226,7 @@ static void *silc_socket_host_lookup_start(void *context)
   if (lookup->port)
     sock->port = silc_net_get_remote_port(sock->sock);
 
-  silc_net_check_host_by_sock(sock->sock, &sock->hostname, &sock->ip);  
+  silc_net_check_host_by_sock(sock->sock, &sock->hostname, &sock->ip);
   if (!sock->hostname && sock->ip)
     sock->hostname = strdup(sock->ip);
 
index e8f3356cdae300e1c8ae6ea39c0f51461a8808c8..960da4bbd194dfe872d44c2d13fced6f334d690d 100644 (file)
@@ -1,16 +1,15 @@
 /*
+
   silcsockconn.h
+
   Author: Pekka Riikonen <priikone@silnet.org>
-  Copyright (C) 1997 - 2001 Pekka Riikonen
+
+  Copyright (C) 1997 - 2001, 2003 Pekka Riikonen
+
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -36,7 +35,7 @@
 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnection
  *
  * NAME
- * 
+ *
  *    typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
  *
  * DESCRIPTION
@@ -54,14 +53,14 @@ typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHB
  *
  * NAME
- * 
+ *
  *    typedef struct SilcSocketConnectionHB *SilcSocketConnectionHB;
  *
  * DESCRIPTION
  *
  *    This context is the heartbeat context for the SilcSockeConnection.
  *    It is meant to hold the keepalive information for the connection.
- *    This is allocated internally and freed internally by the 
+ *    This is allocated internally and freed internally by the
  *    interface routines.
  *
  ***/
@@ -70,7 +69,7 @@ typedef struct SilcSocketConnectionHBStruct *SilcSocketConnectionHB;
 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionQos
  *
  * NAME
- * 
+ *
  *    typedef struct SilcSocketConnectionQosStruct *SilcSocketConnectionQos;
  *
  * DESCRIPTION
@@ -90,12 +89,13 @@ typedef struct SilcSocketConnectionQosStruct {
   unsigned int cur_rate : 31;
   unsigned int applied  : 1;
   SilcUInt32 data_len;
+  SilcSocketConnection sock;
 } *SilcSocketConnectionQos;
 
 /****d* silcutil/SilcSocketConnectionAPI/SilcSocketType
  *
  * NAME
- * 
+ *
  *    typedef enum { ... } SilcSocketType;
  *
  * DESCRIPTION
@@ -104,7 +104,7 @@ typedef struct SilcSocketConnectionQosStruct {
  *    are four different types; unknown, client, server and router.
  *    Unknown connections are connections that hasn't advanced long
  *    enough so that we might know which type of connection it is.
- *    It is the applications responsibility to update the type 
+ *    It is the applications responsibility to update the type
  *    information when it becomes available.
  *
  * SOURCE
@@ -131,7 +131,7 @@ typedef enum {
 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionStruct
  *
  * NAME
- * 
+ *
  *    struct SilcSocketConnectionStruct { ... };
  *
  * DESCRIPTION
@@ -158,7 +158,7 @@ typedef enum {
  *    void *user_data
  *
  *      This is a pointer to a data that is is saved here at the same
- *      time a new connection object is allocated. Usually this is a 
+ *      time a new connection object is allocated. Usually this is a
  *      back-pointer to some important data for fast referencing. For
  *      SILC server this is a pointer to the ID list and for SILC client
  *      to object holding active connections (windows).
@@ -272,7 +272,7 @@ struct SilcSocketConnectionStruct {
  *
  * DESCRIPTION
  *
- *    Allocates a new socket connection object. The allocated object is 
+ *    Allocates a new socket connection object. The allocated object is
  *    returned to the new_socket argument. The `sock' is the socket
  *    for the connection, the `type' the initial type of the connection and
  *    the `user_data' a application specific pointer.
@@ -339,7 +339,7 @@ int silc_socket_read(SilcSocketConnection sock);
  * DESCRIPTION
  *
  *    Writes data from the outgoing buffer to the socket connection. If the
- *    data cannot be written at once, it must be written at later time. 
+ *    data cannot be written at once, it must be written at later time.
  *    The data is written from the data section of the buffer, not from head
  *    or tail section. This automatically pulls the data section towards end
  *    after writing the data. Implementation of this function may be
@@ -386,7 +386,7 @@ typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
  *
  * SYNOPSIS
  *
- *    void silc_socket_set_heartbeat(SilcSocketConnection sock, 
+ *    void silc_socket_set_heartbeat(SilcSocketConnection sock,
  *                                   SilcUInt32 heartbeat,
  *                                   void *hb_context,
  *                                   SilcSocketConnectionHBCb hb_callback,
@@ -403,7 +403,7 @@ typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
  *    application's scheduler.
  *
  ***/
-void silc_socket_set_heartbeat(SilcSocketConnection sock, 
+void silc_socket_set_heartbeat(SilcSocketConnection sock,
                               SilcUInt32 heartbeat,
                               void *hb_context,
                               SilcSocketConnectionHBCb hb_callback,
@@ -413,7 +413,7 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock,
  *
  * SYNOPSIS
  *
- *    void silc_socket_set_qos(SilcSocketConnection sock, 
+ *    void silc_socket_set_qos(SilcSocketConnection sock,
  *                             SilcUInt32 read_rate,
  *                             SilcUInt32 read_limit_bytes,
  *                             SilcUInt32 limit_sec,
@@ -429,12 +429,12 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock,
  *    that is read.  It is guaranteed that silc_socket_read never returns
  *    more that `read_limit_bytes' of data.  If more is read the limit
  *    will be applied for the reading.  The `limit_sec' and `limit_usec'
- *    specifies the limit that is applied if `read_rate' and/or 
+ *    specifies the limit that is applied if `read_rate' and/or
  *    `read_limit_bytes' is reached.  The `schedule' is the application's
  *    scheduler.
  *
  ***/
-void silc_socket_set_qos(SilcSocketConnection sock, 
+void silc_socket_set_qos(SilcSocketConnection sock,
                         SilcUInt32 read_rate,
                         SilcUInt32 read_limit_bytes,
                         SilcUInt32 limit_sec,
@@ -474,16 +474,16 @@ typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
  *    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 `schedule'
- *    is the application's scheduler which the lookup routine needs. 
+ *    is the application's scheduler 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 
+ *    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 
+ *    includes the IP address of the remote host. The resolved port is
  *    available in sock->port.
  *
  ***/
index 26d9dd73a15e362f138f25281288c11f059ae815..821e4f86300b908779eac1db77300880cb4cc85f 100644 (file)
@@ -4,13 +4,12 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2001 Pekka Riikonen
+  Copyright (C) 1997 - 2003 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -22,7 +21,7 @@
 #include "silcincludes.h"
 
 /* Writes data from encrypted buffer to the socket connection. If the
-   data cannot be written at once, it will be written later with a timeout. 
+   data cannot be written at once, it will be written later with a timeout.
    The data is written from the data section of the buffer, not from head
    or tail section. This automatically pulls the data section towards end
    after writing the data. */
@@ -72,12 +71,15 @@ int silc_socket_write(SilcSocketConnection sock)
 
 SILC_TASK_CALLBACK(silc_socket_read_qos)
 {
-  SilcSocketConnection sock = context;
-  sock->qos->applied = TRUE;
+  SilcSocketConnectionQos qos = context;
+  SilcSocketConnection sock = qos->sock;
+  qos->applied = TRUE;
   if (sock->users > 1)
-    silc_schedule_set_listen_fd(sock->qos->schedule, sock->sock,
+    silc_schedule_set_listen_fd(qos->schedule, sock->sock,
                                (SILC_TASK_READ | SILC_TASK_WRITE), TRUE);
-  sock->qos->applied = FALSE;
+  else
+    silc_schedule_unset_listen_fd(qos->schedule, sock->sock);
+  qos->applied = FALSE;
   silc_socket_free(sock);
 }
 
@@ -108,14 +110,15 @@ int silc_socket_read(SilcSocketConnection sock)
 
       if (sock->inbuf->len - len > sock->qos->read_limit_bytes) {
        /* Seems we need to apply QoS for the remaining data as well */
+       silc_socket_dup(sock);
        silc_schedule_task_add(sock->qos->schedule, sock->sock,
-                              silc_socket_read_qos, silc_socket_dup(sock),
+                              silc_socket_read_qos, sock->qos,
                               sock->qos->limit_sec, sock->qos->limit_usec,
                               SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
        silc_schedule_unset_listen_fd(sock->qos->schedule, sock->sock);
-      
+
        /* Hide the rest of the data from the buffer. */
-       sock->qos->data_len = (sock->inbuf->len - len - 
+       sock->qos->data_len = (sock->inbuf->len - len -
                               sock->qos->read_limit_bytes);
        silc_buffer_push_tail(sock->inbuf, sock->qos->data_len);
       }
@@ -153,10 +156,10 @@ int silc_socket_read(SilcSocketConnection sock)
 
   if (!sock->inbuf)
     sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE);
-  
+
   /* If the data does not fit to the buffer reallocate it */
   if ((sock->inbuf->end - sock->inbuf->tail) < len)
-    sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen + 
+    sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen +
                                      (len * 2));
   silc_buffer_put_tail(sock->inbuf, buf, len);
   silc_buffer_pull_tail(sock->inbuf, len);
@@ -179,8 +182,9 @@ int silc_socket_read(SilcSocketConnection sock)
 
     /* If we are not withing rate limit apply QoS for the read data */
     if (sock->qos->cur_rate > sock->qos->read_rate) {
+      silc_socket_dup(sock);
       silc_schedule_task_add(sock->qos->schedule, sock->sock,
-                            silc_socket_read_qos, silc_socket_dup(sock),
+                            silc_socket_read_qos, sock->qos,
                             sock->qos->limit_sec, sock->qos->limit_usec,
                             SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
       silc_schedule_unset_listen_fd(sock->qos->schedule, sock->sock);
@@ -198,8 +202,9 @@ int silc_socket_read(SilcSocketConnection sock)
     } else {
       /* Check the byte limit, and do not return more than allowed */
       if (sock->inbuf->len > sock->qos->read_limit_bytes) {
+       silc_socket_dup(sock);
        silc_schedule_task_add(sock->qos->schedule, sock->sock,
-                              silc_socket_read_qos, silc_socket_dup(sock),
+                              silc_socket_read_qos, sock->qos,
                               sock->qos->limit_sec, sock->qos->limit_usec,
                               SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
        silc_schedule_unset_listen_fd(sock->qos->schedule, sock->sock);