5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "silcincludes.h"
24 /* Writes data from encrypted buffer to the socket connection. If the
25 data cannot be written at once, it will be written later with a timeout.
26 The data is written from the data section of the buffer, not from head
27 or tail section. This automatically pulls the data section towards end
28 after writing the data. */
30 int silc_socket_write(SilcSocketConnection sock)
33 SOCKET fd = sock->sock;
34 SilcBuffer src = sock->outbuf;
36 if (SILC_IS_DISABLED(sock))
39 SILC_LOG_DEBUG(("Writing data to socket %d", fd));
42 ret = send(fd, src->data, src->len, 0);
43 if (ret == SOCKET_ERROR) {
44 err = WSAGetLastError();
45 if (err == WSAEWOULDBLOCK) {
46 SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
49 SILC_LOG_ERROR(("Cannot write to socket: %d", (int)fd));
50 sock->sock_error = err;
55 SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
57 silc_buffer_pull(src, ret);
61 silc_buffer_pull(src, ret);
64 SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
69 /* Reads data from the socket connection into the incoming data buffer.
70 It reads as much as possible from the socket connection. This returns
71 amount of bytes read or -1 on error or -2 on case where all of the
72 data could not be read at once. */
74 int silc_socket_read(SilcSocketConnection sock)
77 unsigned char buf[SILC_SOCKET_READ_SIZE];
78 SOCKET fd = sock->sock;
81 if (SILC_IS_DISABLED(sock))
84 SILC_LOG_DEBUG(("Reading data from socket %d", fd));
86 /* Check whether there is data available, without calling recv(). */
87 ioctlsocket(fd, FIONREAD, (unsigned long *)&argp);
89 /* Is this kludge or what? Without this thing this contraption
90 does not work at all!?. */
92 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
96 /* Read the data from the socket. */
97 len = recv(fd, buf, sizeof(buf), 0);
98 if (len == SOCKET_ERROR) {
99 err = WSAGetLastError();
100 if (err == WSAEWOULDBLOCK || err == WSAEINTR) {
101 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
104 SILC_LOG_ERROR(("Cannot read from socket: %d", (int)fd));
105 sock->sock_error = err;
112 /* Insert the data to the buffer. */
115 sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE);
117 /* If the data does not fit to the buffer reallocate it */
118 if ((sock->inbuf->end - sock->inbuf->tail) < len)
119 sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen +
121 silc_buffer_put_tail(sock->inbuf, buf, len);
122 silc_buffer_pull_tail(sock->inbuf, len);
124 SILC_LOG_DEBUG(("Read %d bytes", len));
129 /* Returns human readable socket error message */
131 bool silc_socket_get_error(SilcSocketConnection sock, char *error,
132 SilcUInt32 error_len)