Create BIO_read_ex() which handles size_t arguments
[oweals/openssl.git] / crypto / bio / bss_sock.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <errno.h>
12 #define USE_SOCKETS
13 #include "bio_lcl.h"
14 #include "internal/cryptlib.h"
15
16 #ifndef OPENSSL_NO_SOCK
17
18 # include <openssl/bio.h>
19
20 # ifdef WATT32
21 /* Watt-32 uses same names */
22 #  undef sock_write
23 #  undef sock_read
24 #  undef sock_puts
25 #  define sock_write SockWrite
26 #  define sock_read  SockRead
27 #  define sock_puts  SockPuts
28 # endif
29
30 static int sock_write(BIO *h, const char *buf, int num);
31 static int sock_read(BIO *h, char *buf, int size);
32 static int sock_puts(BIO *h, const char *str);
33 static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
34 static int sock_new(BIO *h);
35 static int sock_free(BIO *data);
36 int BIO_sock_should_retry(int s);
37
38 static const BIO_METHOD methods_sockp = {
39     BIO_TYPE_SOCKET,
40     "socket",
41     sock_write,
42     /* TODO: Convert to new style read function */
43     bread_conv,
44     sock_read,
45     sock_puts,
46     NULL,                       /* sock_gets, */
47     sock_ctrl,
48     sock_new,
49     sock_free,
50     NULL,
51 };
52
53 const BIO_METHOD *BIO_s_socket(void)
54 {
55     return (&methods_sockp);
56 }
57
58 BIO *BIO_new_socket(int fd, int close_flag)
59 {
60     BIO *ret;
61
62     ret = BIO_new(BIO_s_socket());
63     if (ret == NULL)
64         return (NULL);
65     BIO_set_fd(ret, fd, close_flag);
66     return (ret);
67 }
68
69 static int sock_new(BIO *bi)
70 {
71     bi->init = 0;
72     bi->num = 0;
73     bi->ptr = NULL;
74     bi->flags = 0;
75     return (1);
76 }
77
78 static int sock_free(BIO *a)
79 {
80     if (a == NULL)
81         return (0);
82     if (a->shutdown) {
83         if (a->init) {
84             BIO_closesocket(a->num);
85         }
86         a->init = 0;
87         a->flags = 0;
88     }
89     return (1);
90 }
91
92 static int sock_read(BIO *b, char *out, int outl)
93 {
94     int ret = 0;
95
96     if (out != NULL) {
97         clear_socket_error();
98         ret = readsocket(b->num, out, outl);
99         BIO_clear_retry_flags(b);
100         if (ret <= 0) {
101             if (BIO_sock_should_retry(ret))
102                 BIO_set_retry_read(b);
103         }
104     }
105     return (ret);
106 }
107
108 static int sock_write(BIO *b, const char *in, int inl)
109 {
110     int ret;
111
112     clear_socket_error();
113     ret = writesocket(b->num, in, inl);
114     BIO_clear_retry_flags(b);
115     if (ret <= 0) {
116         if (BIO_sock_should_retry(ret))
117             BIO_set_retry_write(b);
118     }
119     return (ret);
120 }
121
122 static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
123 {
124     long ret = 1;
125     int *ip;
126
127     switch (cmd) {
128     case BIO_C_SET_FD:
129         sock_free(b);
130         b->num = *((int *)ptr);
131         b->shutdown = (int)num;
132         b->init = 1;
133         break;
134     case BIO_C_GET_FD:
135         if (b->init) {
136             ip = (int *)ptr;
137             if (ip != NULL)
138                 *ip = b->num;
139             ret = b->num;
140         } else
141             ret = -1;
142         break;
143     case BIO_CTRL_GET_CLOSE:
144         ret = b->shutdown;
145         break;
146     case BIO_CTRL_SET_CLOSE:
147         b->shutdown = (int)num;
148         break;
149     case BIO_CTRL_DUP:
150     case BIO_CTRL_FLUSH:
151         ret = 1;
152         break;
153     default:
154         ret = 0;
155         break;
156     }
157     return (ret);
158 }
159
160 static int sock_puts(BIO *bp, const char *str)
161 {
162     int n, ret;
163
164     n = strlen(str);
165     ret = sock_write(bp, str, n);
166     return (ret);
167 }
168
169 int BIO_sock_should_retry(int i)
170 {
171     int err;
172
173     if ((i == 0) || (i == -1)) {
174         err = get_last_socket_error();
175
176         return (BIO_sock_non_fatal_error(err));
177     }
178     return (0);
179 }
180
181 int BIO_sock_non_fatal_error(int err)
182 {
183     switch (err) {
184 # if defined(OPENSSL_SYS_WINDOWS)
185 #  if defined(WSAEWOULDBLOCK)
186     case WSAEWOULDBLOCK:
187 #  endif
188 # endif
189
190 # ifdef EWOULDBLOCK
191 #  ifdef WSAEWOULDBLOCK
192 #   if WSAEWOULDBLOCK != EWOULDBLOCK
193     case EWOULDBLOCK:
194 #   endif
195 #  else
196     case EWOULDBLOCK:
197 #  endif
198 # endif
199
200 # if defined(ENOTCONN)
201     case ENOTCONN:
202 # endif
203
204 # ifdef EINTR
205     case EINTR:
206 # endif
207
208 # ifdef EAGAIN
209 #  if EWOULDBLOCK != EAGAIN
210     case EAGAIN:
211 #  endif
212 # endif
213
214 # ifdef EPROTO
215     case EPROTO:
216 # endif
217
218 # ifdef EINPROGRESS
219     case EINPROGRESS:
220 # endif
221
222 # ifdef EALREADY
223     case EALREADY:
224 # endif
225         return (1);
226         /* break; */
227     default:
228         break;
229     }
230     return (0);
231 }
232
233 #endif                          /* #ifndef OPENSSL_NO_SOCK */