GNU General Public License for more details.
*/
-/*
- * $Id$
- * $Log$
- * Revision 1.1 2000/06/27 11:36:55 priikone
- * Initial revision
- *
- *
- */
+/* $Id$ */
#include "silcincludes.h"
{
SILC_LOG_DEBUG(("Allocating new socket connection object"));
- *new_socket = silc_calloc(1, sizeof(**new_socket));
- if (*new_socket == NULL) {
- SILC_LOG_ERROR(("Could not allocate new socket connection object"));
- return;
- }
-
/* Set the pointers. Incoming and outgoing data buffers
- are allocated by the server when they are first used. */
+ are allocated by the application when they are first used. */
+ *new_socket = silc_calloc(1, sizeof(**new_socket));
(*new_socket)->sock = sock;
(*new_socket)->type = type;
(*new_socket)->user_data = user_data;
(*new_socket)->flags = 0;
(*new_socket)->inbuf = NULL;
(*new_socket)->outbuf = NULL;
+ (*new_socket)->users++;
}
/* Free's the Socket connection object. */
void silc_socket_free(SilcSocketConnection sock)
{
- if (sock) {
- // silc_protocol_free(sock->protocol);
+ sock->users--;
+ SILC_LOG_DEBUG(("Socket %p refcnt %d->%d", sock, sock->users + 1,
+ sock->users));
+ if (sock->users < 1) {
silc_buffer_free(sock->inbuf);
silc_buffer_free(sock->outbuf);
+ if (sock->hb) {
+ silc_task_unregister(sock->hb->timeout_queue, sock->hb->hb_task);
+ silc_free(sock->hb->hb_context);
+ silc_free(sock->hb);
+ }
+
+ memset(sock, 'F', sizeof(*sock));
silc_free(sock);
}
}
+
+/* Increase the reference counter. */
+
+SilcSocketConnection silc_socket_dup(SilcSocketConnection sock)
+{
+ sock->users++;
+ SILC_LOG_DEBUG(("Socket %p refcnt %d->%d", sock, sock->users - 1,
+ sock->users));
+ return sock;
+}
+
+/* Internal timeout callback to perform heartbeat */
+
+SILC_TASK_CALLBACK(silc_socket_heartbeat)
+{
+ SilcSocketConnectionHB hb = (SilcSocketConnectionHB)context;
+
+ if (!hb->heartbeat)
+ return;
+
+ if (hb->hb_callback)
+ hb->hb_callback(hb->sock, hb->hb_context);
+
+ hb->hb_task = silc_task_register(hb->timeout_queue, hb->sock->sock,
+ silc_socket_heartbeat,
+ context, hb->heartbeat, 0,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_LOW);
+}
+
+/* Sets the heartbeat timeout and prepares the socket for performing
+ heartbeat in `heartbeat' intervals (seconds). The `hb_context' is
+ allocated by the application and will be sent as argument to the
+ `hb_callback' function that is called when the `heartbeat' timeout
+ expires. The callback `hb_context' won't be touched by the library
+ but will be freed automatically when calling silc_socket_free. The
+ `timeout_queue' is the application's scheduler timeout queue. */
+
+void silc_socket_set_heartbeat(SilcSocketConnection sock,
+ uint32 heartbeat,
+ void *hb_context,
+ SilcSocketConnectionHBCb hb_callback,
+ void *timeout_queue)
+{
+
+ if (sock->hb) {
+ silc_task_unregister(sock->hb->timeout_queue, sock->hb->hb_task);
+ silc_free(sock->hb->hb_context);
+ silc_free(sock->hb);
+ }
+
+ sock->hb = silc_calloc(1, sizeof(*sock->hb));
+ sock->hb->heartbeat = heartbeat;
+ sock->hb->hb_context = hb_context;
+ sock->hb->hb_callback = hb_callback;
+ sock->hb->timeout_queue = timeout_queue;
+ sock->hb->sock = sock;
+ sock->hb->hb_task = silc_task_register(timeout_queue, sock->sock,
+ silc_socket_heartbeat,
+ (void *)sock->hb, heartbeat, 0,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_LOW);
+}