From d4851c1ca23bb52c9740a0c03110ced0616631e8 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 18 Oct 2003 11:26:30 +0000 Subject: [PATCH] Unregister qos tasks when deleting socket. --- lib/silcutil/silcsockconn.c | 27 ++++++++------- lib/silcutil/silcsockconn.h | 52 ++++++++++++++-------------- lib/silcutil/unix/silcunixsockconn.c | 37 +++++++++++--------- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/lib/silcutil/silcsockconn.c b/lib/silcutil/silcsockconn.c index a4942248..4a57a343 100644 --- a/lib/silcutil/silcsockconn.c +++ b/lib/silcutil/silcsockconn.c @@ -4,13 +4,12 @@ Author: Pekka Riikonen - 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); diff --git a/lib/silcutil/silcsockconn.h b/lib/silcutil/silcsockconn.h index e8f3356c..960da4bb 100644 --- a/lib/silcutil/silcsockconn.h +++ b/lib/silcutil/silcsockconn.h @@ -1,16 +1,15 @@ /* - + silcsockconn.h - + Author: Pekka Riikonen - - 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. * ***/ diff --git a/lib/silcutil/unix/silcunixsockconn.c b/lib/silcutil/unix/silcunixsockconn.c index 26d9dd73..821e4f86 100644 --- a/lib/silcutil/unix/silcunixsockconn.c +++ b/lib/silcutil/unix/silcunixsockconn.c @@ -4,13 +4,12 @@ Author: Pekka Riikonen - 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); -- 2.24.0