Merged from silc_1_0_branch.
[silc.git] / lib / silcutil / silcsockconn.c
index 25a56fe1aa658de5398f2502063c1da450cea65a..6817c5daea20f98150f7c52b3e9f4a696bc97e3e 100644 (file)
@@ -75,7 +75,7 @@ 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);
     silc_free(sock->ip);
     silc_free(sock->hostname);
 
@@ -145,6 +145,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. */
@@ -160,8 +192,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;
   }