X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcsockconn.c;h=a49422487a0329c1262989edbe2ff790fce95248;hb=413da0f8686910f5e627393157566ae729ca99c4;hp=942b30d8664e37ef46b36fd9762d39ccce7219da;hpb=0d83f43ff41af4950a7cda27a59fce6f8973311e;p=silc.git diff --git a/lib/silcutil/silcsockconn.c b/lib/silcutil/silcsockconn.c index 942b30d8..a4942248 100644 --- a/lib/silcutil/silcsockconn.c +++ b/lib/silcutil/silcsockconn.c @@ -23,7 +23,7 @@ /* Heartbeat context */ struct SilcSocketConnectionHBStruct { - uint32 heartbeat; + SilcUInt32 heartbeat; SilcSocketConnectionHBCb hb_callback; void *hb_context; SilcSchedule schedule; @@ -73,9 +73,11 @@ void silc_socket_free(SilcSocketConnection sock) silc_buffer_free(sock->outbuf); if (sock->hb) { silc_schedule_task_del(sock->hb->schedule, sock->hb->hb_task); - silc_free(sock->hb->hb_context); silc_free(sock->hb); } + silc_free(sock->qos); + silc_free(sock->ip); + silc_free(sock->hostname); memset(sock, 'F', sizeof(*sock)); silc_free(sock); @@ -101,6 +103,10 @@ SILC_TASK_CALLBACK(silc_socket_heartbeat) if (!hb->heartbeat) return; + if (SILC_IS_DISCONNECTING(hb->sock) || + SILC_IS_DISCONNECTED(hb->sock)) + return; + if (hb->hb_callback) hb->hb_callback(hb->sock, hb->hb_context); @@ -120,14 +126,13 @@ SILC_TASK_CALLBACK(silc_socket_heartbeat) `schedule' is the application's scheduler. */ void silc_socket_set_heartbeat(SilcSocketConnection sock, - uint32 heartbeat, + SilcUInt32 heartbeat, void *hb_context, SilcSocketConnectionHBCb hb_callback, SilcSchedule schedule) { if (sock->hb) { silc_schedule_task_del(schedule, sock->hb->hb_task); - silc_free(sock->hb->hb_context); silc_free(sock->hb); } @@ -144,6 +149,38 @@ void silc_socket_set_heartbeat(SilcSocketConnection sock, SILC_TASK_PRI_LOW); } +/* Sets a "Quality of Service" settings for socket connection `sock'. + The `read_rate' specifies the maximum read operations per second. + If more read operations are executed the limit will be applied for + the reading. The `read_limit_bytes' specifies the maximum data + 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 + `read_limit_bytes' is reached. The `schedule' is the application's + scheduler. */ + +void silc_socket_set_qos(SilcSocketConnection sock, + SilcUInt32 read_rate, + SilcUInt32 read_limit_bytes, + SilcUInt32 limit_sec, + SilcUInt32 limit_usec, + SilcSchedule schedule) +{ + if (!sock->qos) { + sock->qos = silc_calloc(1, sizeof(*sock->qos)); + if (!sock->qos) + return; + } + sock->qos->read_rate = read_rate; + sock->qos->read_limit_bytes = read_limit_bytes; + sock->qos->limit_sec = limit_sec; + sock->qos->limit_usec = limit_usec; + sock->qos->schedule = schedule; + memset(&sock->qos->next_limit, 0, sizeof(sock->qos->next_limit)); + sock->qos->cur_rate = 0; +} + /* 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. */ @@ -159,8 +196,8 @@ SILC_TASK_CALLBACK(silc_socket_host_lookup_finish) 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); + silc_free(lookup); return; } @@ -181,6 +218,7 @@ static void *silc_socket_host_lookup_start(void *context) { SilcSocketHostLookup lookup = (SilcSocketHostLookup)context; SilcSocketConnection sock = lookup->sock; + SilcSchedule schedule = lookup->schedule; if (lookup->port) sock->port = silc_net_get_remote_port(sock->sock); @@ -189,10 +227,10 @@ static void *silc_socket_host_lookup_start(void *context) if (!sock->hostname && sock->ip) sock->hostname = strdup(sock->ip); - silc_schedule_task_add(lookup->schedule, sock->sock, + silc_schedule_task_add(schedule, sock->sock, silc_socket_host_lookup_finish, lookup, 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); - silc_schedule_wakeup(lookup->schedule); + silc_schedule_wakeup(schedule); return NULL; } @@ -216,6 +254,10 @@ void silc_socket_host_lookup(SilcSocketConnection sock, SILC_LOG_DEBUG(("Performing async host lookup")); + if (SILC_IS_DISCONNECTING(sock) || + SILC_IS_DISCONNECTED(sock)) + return; + lookup = silc_calloc(1, sizeof(*lookup)); lookup->sock = silc_socket_dup(sock); /* Increase reference counter */ lookup->callback = callback; @@ -224,10 +266,5 @@ void silc_socket_host_lookup(SilcSocketConnection sock, lookup->port = port_lookup; SILC_SET_HOST_LOOKUP(sock); - -#ifdef SILC_THREADS silc_thread_create(silc_socket_host_lookup_start, lookup, FALSE); -#else - silc_socket_host_lookup_start((void *)lookup); -#endif }