1 /* 2 * Copyright 1995-2020 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_local.h" 13 #include "internal/cryptlib.h" 14 #include "internal/ktls.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 /* TODO: Convert to new style write function */ 42 bwrite_conv, 43 sock_write, 44 /* TODO: Convert to new style read function */ 45 bread_conv, 46 sock_read, 47 sock_puts, 48 NULL, /* sock_gets, */ 49 sock_ctrl, 50 sock_new, 51 sock_free, 52 NULL, /* sock_callback_ctrl */ 53 }; 54 55 const BIO_METHOD *BIO_s_socket(void) 56 { 57 return &methods_sockp; 58 } 59 60 BIO *BIO_new_socket(int fd, int close_flag) 61 { 62 BIO *ret; 63 64 ret = BIO_new(BIO_s_socket()); 65 if (ret == NULL) 66 return NULL; 67 BIO_set_fd(ret, fd, close_flag); 68 # ifndef OPENSSL_NO_KTLS 69 { 70 /* 71 * The new socket is created successfully regardless of ktls_enable. 72 * ktls_enable doesn't change any functionality of the socket, except 73 * changing the setsockopt to enable the processing of ktls_start. 74 * Thus, it is not a problem to call it for non-TLS sockets. 75 */ 76 ktls_enable(fd); 77 } 78 # endif 79 return ret; 80 } 81 82 static int sock_new(BIO *bi) 83 { 84 bi->init = 0; 85 bi->num = 0; 86 bi->ptr = NULL; 87 bi->flags = 0; 88 return 1; 89 } 90 91 static int sock_free(BIO *a) 92 { 93 if (a == NULL) 94 return 0; 95 if (a->shutdown) { 96 if (a->init) { 97 BIO_closesocket(a->num); 98 } 99 a->init = 0; 100 a->flags = 0; 101 } 102 return 1; 103 } 104 105 static int sock_read(BIO *b, char *out, int outl) 106 { 107 int ret = 0; 108 109 if (out != NULL) { 110 clear_socket_error(); 111 # ifndef OPENSSL_NO_KTLS 112 if (BIO_get_ktls_recv(b)) 113 ret = ktls_read_record(b->num, out, outl); 114 else 115 # endif 116 ret = readsocket(b->num, out, outl); 117 BIO_clear_retry_flags(b); 118 if (ret <= 0) { 119 if (BIO_sock_should_retry(ret)) 120 BIO_set_retry_read(b); 121 else if (ret == 0) 122 b->flags |= BIO_FLAGS_IN_EOF; 123 } 124 } 125 return ret; 126 } 127 128 static int sock_write(BIO *b, const char *in, int inl) 129 { 130 int ret = 0; 131 132 clear_socket_error(); 133 # ifndef OPENSSL_NO_KTLS 134 if (BIO_should_ktls_ctrl_msg_flag(b)) { 135 unsigned char record_type = (intptr_t)b->ptr; 136 ret = ktls_send_ctrl_message(b->num, record_type, in, inl); 137 if (ret >= 0) { 138 ret = inl; 139 BIO_clear_ktls_ctrl_msg_flag(b); 140 } 141 } else 142 # endif 143 ret = writesocket(b->num, in, inl); 144 BIO_clear_retry_flags(b); 145 if (ret <= 0) { 146 if (BIO_sock_should_retry(ret)) 147 BIO_set_retry_write(b); 148 } 149 return ret; 150 } 151 152 static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) 153 { 154 long ret = 1; 155 int *ip; 156 # ifndef OPENSSL_NO_KTLS 157 ktls_crypto_info_t *crypto_info; 158 # endif 159 160 switch (cmd) { 161 case BIO_C_SET_FD: 162 sock_free(b); 163 b->num = *((int *)ptr); 164 b->shutdown = (int)num; 165 b->init = 1; 166 break; 167 case BIO_C_GET_FD: 168 if (b->init) { 169 ip = (int *)ptr; 170 if (ip != NULL) 171 *ip = b->num; 172 ret = b->num; 173 } else 174 ret = -1; 175 break; 176 case BIO_CTRL_GET_CLOSE: 177 ret = b->shutdown; 178 break; 179 case BIO_CTRL_SET_CLOSE: 180 b->shutdown = (int)num; 181 break; 182 case BIO_CTRL_DUP: 183 case BIO_CTRL_FLUSH: 184 ret = 1; 185 break; 186 # ifndef OPENSSL_NO_KTLS 187 case BIO_CTRL_SET_KTLS: 188 crypto_info = (ktls_crypto_info_t *)ptr; 189 ret = ktls_start(b->num, crypto_info, num); 190 if (ret) 191 BIO_set_ktls_flag(b, num); 192 break; 193 case BIO_CTRL_GET_KTLS_SEND: 194 return BIO_should_ktls_flag(b, 1) != 0; 195 case BIO_CTRL_GET_KTLS_RECV: 196 return BIO_should_ktls_flag(b, 0) != 0; 197 case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG: 198 BIO_set_ktls_ctrl_msg_flag(b); 199 b->ptr = (void *)num; 200 ret = 0; 201 break; 202 case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG: 203 BIO_clear_ktls_ctrl_msg_flag(b); 204 ret = 0; 205 break; 206 # endif 207 case BIO_CTRL_EOF: 208 ret = (b->flags & BIO_FLAGS_IN_EOF) != 0; 209 break; 210 default: 211 ret = 0; 212 break; 213 } 214 return ret; 215 } 216 217 static int sock_puts(BIO *bp, const char *str) 218 { 219 int n, ret; 220 221 n = strlen(str); 222 ret = sock_write(bp, str, n); 223 return ret; 224 } 225 226 int BIO_sock_should_retry(int i) 227 { 228 int err; 229 230 if ((i == 0) || (i == -1)) { 231 err = get_last_socket_error(); 232 233 return BIO_sock_non_fatal_error(err); 234 } 235 return 0; 236 } 237 238 int BIO_sock_non_fatal_error(int err) 239 { 240 switch (err) { 241 # if defined(OPENSSL_SYS_WINDOWS) 242 # if defined(WSAEWOULDBLOCK) 243 case WSAEWOULDBLOCK: 244 # endif 245 # endif 246 247 # ifdef EWOULDBLOCK 248 # ifdef WSAEWOULDBLOCK 249 # if WSAEWOULDBLOCK != EWOULDBLOCK 250 case EWOULDBLOCK: 251 # endif 252 # else 253 case EWOULDBLOCK: 254 # endif 255 # endif 256 257 # if defined(ENOTCONN) 258 case ENOTCONN: 259 # endif 260 261 # ifdef EINTR 262 case EINTR: 263 # endif 264 265 # ifdef EAGAIN 266 # if EWOULDBLOCK != EAGAIN 267 case EAGAIN: 268 # endif 269 # endif 270 271 # ifdef EPROTO 272 case EPROTO: 273 # endif 274 275 # ifdef EINPROGRESS 276 case EINPROGRESS: 277 # endif 278 279 # ifdef EALREADY 280 case EALREADY: 281 # endif 282 return 1; 283 default: 284 break; 285 } 286 return 0; 287 } 288 289 #endif /* #ifndef OPENSSL_NO_SOCK */ 290