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