Coverage Report

Created: 2018-08-29 13:53

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