X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcsocketstream.c;h=e4b59f5a601c6d0019632438514f780a48729507;hb=196824372226561334cd638d6471267cbffb354c;hp=1c4e952a232cd1540075f180f1d207d2e95ebb54;hpb=609978b52bc2d6a26ef98cacd35bed5cde0714e7;p=silc.git diff --git a/lib/silcutil/silcsocketstream.c b/lib/silcutil/silcsocketstream.c index 1c4e952a..e4b59f5a 100644 --- a/lib/silcutil/silcsocketstream.c +++ b/lib/silcutil/silcsocketstream.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2005 - 2006 Pekka Riikonen + Copyright (C) 2005 - 2007 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 @@ -21,13 +21,7 @@ /************************** Types and definitions ***************************/ -#define SILC_IS_SOCKET_STREAM(s) (s->ops == &silc_socket_stream_ops) -#define SILC_IS_SOCKET_STREAM_UDP(s) (s->ops == &silc_socket_udp_stream_ops) - -const SilcStreamOps silc_socket_stream_ops; -const SilcStreamOps silc_socket_udp_stream_ops; - -/* Platform specific functions */ +/* Stream operation functions (platform specific) */ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, SilcUInt32 buf_len); int silc_socket_stream_write(SilcStream stream, const unsigned char *data, @@ -38,6 +32,13 @@ int silc_socket_udp_stream_read(SilcStream stream, unsigned char *buf, SilcUInt32 buf_len); int silc_socket_udp_stream_write(SilcStream stream, const unsigned char *data, SilcUInt32 data_len); +SilcBool silc_socket_stream_close(SilcStream stream); +void silc_socket_stream_destroy(SilcStream stream); +SilcBool silc_socket_stream_notifier(SilcStream stream, + SilcSchedule schedule, + SilcStreamNotifier callback, + void *context); +SilcSchedule silc_socket_stream_get_schedule(SilcStream stream); /* Internal async host lookup context. */ typedef struct { @@ -53,30 +54,6 @@ typedef struct { /************************ Static utility functions **************************/ -/* The IO process callback that calls the notifier callback to upper - layer. */ - -SILC_TASK_CALLBACK(silc_socket_stream_io) -{ - SilcSocketStream stream = context; - - if (silc_unlikely(!stream->notifier)) - return; - - switch (type) { - case SILC_TASK_READ: - stream->notifier(stream, SILC_STREAM_CAN_READ, stream->notifier_context); - break; - - case SILC_TASK_WRITE: - stream->notifier(stream, SILC_STREAM_CAN_WRITE, stream->notifier_context); - break; - - default: - break; - } -} - /* 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. */ @@ -88,20 +65,16 @@ SILC_TASK_CALLBACK(silc_socket_host_lookup_finish) if (lookup->aborted) { SILC_LOG_DEBUG(("Socket stream creation was aborted")); - silc_net_close_connection(stream->sock); - silc_free(stream->ip); - silc_free(stream->hostname); - silc_free(stream); + stream->schedule = NULL; + silc_socket_stream_destroy(stream); silc_free(lookup); return; } if (lookup->status != SILC_SOCKET_OK) { - SILC_LOG_DEBUG(("Socket stream failed")); - silc_net_close_connection(stream->sock); - silc_free(stream->ip); - silc_free(stream->hostname); - silc_free(stream); + SILC_LOG_DEBUG(("Socket stream lookup failed")); + stream->schedule = NULL; + silc_socket_stream_destroy(stream); stream = lookup->stream = NULL; } @@ -170,7 +143,7 @@ static void silc_socket_host_lookup_abort(SilcAsyncOperation op, /* Creates TCP socket stream */ SilcAsyncOperation -silc_socket_tcp_stream_create(int sock, SilcBool lookup, +silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup, SilcBool require_fqdn, SilcSchedule schedule, SilcSocketStreamCallback callback, @@ -179,6 +152,13 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup, SilcSocketStream stream; SilcSocketHostLookup l; + if (!sock || !schedule) { + SILC_LOG_ERROR(("Missing arguments to silc_socket_tcp_stream_create")); + if (callback) + callback(SILC_SOCKET_ERROR, NULL, context); + return NULL; + } + stream = silc_calloc(1, sizeof(*stream)); if (!stream) { if (callback) @@ -186,11 +166,12 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup, return NULL; } - SILC_LOG_DEBUG(("Creating TCP socket stream %p", stream)); + SILC_LOG_DEBUG(("Creating TCP socket stream %p, sock %lu", stream, sock)); stream->ops = &silc_socket_stream_ops; stream->sock = sock; stream->schedule = schedule; + stream->connected = TRUE; l = silc_calloc(1, sizeof(*l)); if (!l) { @@ -232,7 +213,7 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup, /* Creates UDP socket stream */ -SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6, +SilcStream silc_socket_udp_stream_create(SilcSocket sock, SilcBool ipv6, SilcBool connected, SilcSchedule schedule) { @@ -271,7 +252,7 @@ SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected) /* Returns socket stream information */ SilcBool silc_socket_stream_get_info(SilcStream stream, - int *sock, const char **hostname, + SilcSocket *sock, const char **hostname, const char **ip, SilcUInt16 *port) { SilcSocketStream socket_stream = stream; @@ -282,20 +263,20 @@ SilcBool silc_socket_stream_get_info(SilcStream stream, if (sock) *sock = socket_stream->sock; - if (hostname) { - if (!socket_stream->hostname) + if (port) { + if (!socket_stream->port) return FALSE; - *hostname = socket_stream->hostname; + *port = socket_stream->port; } if (ip) { if (!socket_stream->ip) return FALSE; *ip = socket_stream->ip; } - if (port) { - if (!socket_stream->port) + if (hostname) { + if (!socket_stream->hostname) return FALSE; - *port = socket_stream->port; + *hostname = socket_stream->hostname; } return TRUE; @@ -396,91 +377,6 @@ SilcBool silc_socket_stream_set_qos(SilcStream stream, return TRUE; } -/* Closes socket */ - -SilcBool silc_socket_stream_close(SilcStream stream) -{ - SilcSocketStream socket_stream = stream; - - if (!SILC_IS_SOCKET_STREAM(socket_stream) && - !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) - return FALSE; - - silc_schedule_unset_listen_fd(socket_stream->schedule, socket_stream->sock); - silc_net_close_connection(socket_stream->sock); - - return TRUE; -} - -/* Destroys the stream */ - -void silc_socket_stream_destroy(SilcStream stream) -{ - SilcSocketStream socket_stream = stream; - - if (!SILC_IS_SOCKET_STREAM(socket_stream) && - !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) - return; - - silc_socket_stream_close(socket_stream); - silc_free(socket_stream->ip); - silc_free(socket_stream->hostname); - silc_schedule_task_del_by_fd(socket_stream->schedule, socket_stream->sock); - - if (socket_stream->qos) { - silc_schedule_task_del_by_context(socket_stream->schedule, - socket_stream->qos); - if (socket_stream->qos->buffer) { - memset(socket_stream->qos->buffer, 0, - socket_stream->qos->read_limit_bytes); - silc_free(socket_stream->qos->buffer); - } - silc_free(socket_stream->qos); - } - - silc_schedule_wakeup(socket_stream->schedule); - - silc_free(socket_stream); -} - -/* Sets stream notification callback for the stream */ - -void silc_socket_stream_notifier(SilcStream stream, - SilcSchedule schedule, - SilcStreamNotifier callback, - void *context) -{ - SilcSocketStream socket_stream = stream; - - if (!SILC_IS_SOCKET_STREAM(socket_stream) && - !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) - return; - - SILC_LOG_DEBUG(("Setting stream notifier callback")); - - socket_stream->notifier = callback; - socket_stream->notifier_context = context; - socket_stream->schedule = schedule; - - if (socket_stream->notifier) { - /* Add the socket to scheduler. Safe to call if already added. */ - silc_schedule_task_add_fd(socket_stream->schedule, socket_stream->sock, - silc_socket_stream_io, socket_stream); - - /* Initially set socket for reading */ - silc_schedule_set_listen_fd(socket_stream->schedule, socket_stream->sock, - SILC_TASK_READ, FALSE); - silc_schedule_wakeup(socket_stream->schedule); - } else { - /* Unschedule the socket */ - silc_schedule_unset_listen_fd(socket_stream->schedule, - socket_stream->sock); - silc_schedule_task_del_by_fd(socket_stream->schedule, - socket_stream->sock); - silc_schedule_wakeup(socket_stream->schedule); - } -} - /* Return associated scheduler */ SilcSchedule silc_socket_stream_get_schedule(SilcStream stream)