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
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"));
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);
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,
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,
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,
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
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);
/*
-
+
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
/****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnection
*
* NAME
- *
+ *
* typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
*
* DESCRIPTION
/****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.
*
***/
/****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionQos
*
* NAME
- *
+ *
* typedef struct SilcSocketConnectionQosStruct *SilcSocketConnectionQos;
*
* DESCRIPTION
unsigned int cur_rate : 31;
unsigned int applied : 1;
SilcUInt32 data_len;
+ SilcSocketConnection sock;
} *SilcSocketConnectionQos;
/****d* silcutil/SilcSocketConnectionAPI/SilcSocketType
*
* NAME
- *
+ *
* typedef enum { ... } SilcSocketType;
*
* DESCRIPTION
* 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
/****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionStruct
*
* NAME
- *
+ *
* struct SilcSocketConnectionStruct { ... };
*
* DESCRIPTION
* 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).
*
* 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.
* 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
*
* SYNOPSIS
*
- * void silc_socket_set_heartbeat(SilcSocketConnection sock,
+ * void silc_socket_set_heartbeat(SilcSocketConnection sock,
* SilcUInt32 heartbeat,
* void *hb_context,
* SilcSocketConnectionHBCb hb_callback,
* 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,
*
* 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,
* 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,
* 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.
*
***/
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
#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. */
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);
}
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);
}
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);
/* 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);
} 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);