From: Pekka Riikonen Date: Sun, 3 Dec 2006 20:47:43 +0000 (+0000) Subject: Handle error and non-blocking with UDP correctly. X-Git-Tag: silc.client.1.1.beta1~147 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=342761d34b65d06b1fda9b6bf0fd22623b6878d4;p=silc.git Handle error and non-blocking with UDP correctly. --- diff --git a/lib/silcutil/unix/silcunixnet.c b/lib/silcutil/unix/silcunixnet.c index a1326253..805feb87 100644 --- a/lib/silcutil/unix/silcunixnet.c +++ b/lib/silcutil/unix/silcunixnet.c @@ -133,7 +133,7 @@ silc_net_tcp_create_listener(const char **local_ip_addr, SILC_LOG_DEBUG(("Creating TCP listener")); - if (port < 1 || !schedule || !callback) + if (port < 0 || !schedule || !callback) goto err; listener = silc_calloc(1, sizeof(*listener)); @@ -330,7 +330,7 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, stream = silc_socket_udp_stream_create(sock, local_ip_addr ? silc_net_is_ip6(local_ip_addr) : FALSE, - schedule); + remote_ip_addr ? TRUE : FALSE, schedule); if (!stream) goto err; @@ -398,6 +398,8 @@ int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr, inet_ntop(AF_INET, &s.sin.sin_addr, remote_ip_addr, remote_ip_addr_size); } + + SILC_LOG_DEBUG(("UDP packet from %s:%d", remote_ip_addr, remote_port)); } return len; @@ -405,21 +407,41 @@ int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr, /* Send UDP packet */ -void silc_net_udp_send(SilcStream stream, - const char *remote_ip_addr, int remote_port, - const unsigned char *data, SilcUInt32 data_len) +int silc_net_udp_send(SilcStream stream, + const char *remote_ip_addr, int remote_port, + const unsigned char *data, SilcUInt32 data_len) { SilcSocketStream sock = stream; SilcSockaddr remote; + int ret; - SILC_LOG_DEBUG(("Writing data to UDP socket %d", sock->sock)); + SILC_LOG_DEBUG(("Sending data to UDP socket %d", sock->sock)); - /* Set sockaddr for server */ + /* Set sockaddr */ if (!silc_net_set_sockaddr(&remote, remote_ip_addr, remote_port)) - return; + return -2; /* Send */ - sendto(sock->sock, data, data_len, 0, &remote.sa, SIZEOF_SOCKADDR(remote)); + ret = sendto(sock->sock, data, data_len, 0, &remote.sa, + SIZEOF_SOCKADDR(remote)); + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) { + SILC_LOG_DEBUG(("Could not send immediately, will do it later")); + silc_schedule_set_listen_fd(sock->schedule, sock->sock, + SILC_TASK_READ | SILC_TASK_WRITE, FALSE); + return -1; + } + SILC_LOG_DEBUG(("Cannot send to UDP socket: %s", strerror(errno))); + silc_schedule_unset_listen_fd(sock->schedule, sock->sock); + sock->sock_error = errno; + return -2; + } + + SILC_LOG_DEBUG(("Sent data %d bytes", ret)); + silc_schedule_set_listen_fd(sock->schedule, sock->sock, + SILC_TASK_READ, FALSE); + + return ret; } /* Asynchronous TCP/IP connecting */ diff --git a/lib/silcutil/unix/silcunixsocketstream.c b/lib/silcutil/unix/silcunixsocketstream.c index 1eded3d3..8b2f7ff4 100644 --- a/lib/silcutil/unix/silcunixsocketstream.c +++ b/lib/silcutil/unix/silcunixsocketstream.c @@ -188,19 +188,13 @@ int silc_socket_udp_stream_write(SilcStream stream, const unsigned char *data, SilcUInt32 data_len) { SilcSocketStream sock = stream; - int ret; - - SILC_LOG_DEBUG(("Writing data to UDP socket %d", sock->sock)); - ret = send(sock->sock, data, data_len, 0); - if (ret < 0) { - /* Ignore error and return success */ - SILC_LOG_DEBUG(("Cannot write to UDP socket: %s", strerror(errno))); - return data_len; - } + /* In connectionless state check if remote IP and port is provided */ + if (!sock->connected && sock->ip && sock->port) + return silc_net_udp_send(stream, sock->ip, sock->port, data, data_len); - SILC_LOG_DEBUG(("Wrote data %d bytes", ret)); - return ret; + /* In connected state use normal writing to socket. */ + return silc_socket_stream_write(stream, data, data_len); } #if 0