1/* 2 * Copyright 1995-2022 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 <stdlib.h> 12#include "bio_local.h" 13#ifndef OPENSSL_NO_SOCK 14# define SOCKET_PROTOCOL IPPROTO_TCP 15# ifdef SO_MAXCONN 16# define MAX_LISTEN SO_MAXCONN 17# elif defined(SOMAXCONN) 18# define MAX_LISTEN SOMAXCONN 19# else 20# define MAX_LISTEN 32 21# endif 22# if defined(OPENSSL_SYS_WINDOWS) 23static int wsa_init_done = 0; 24# endif 25 26# if defined __TANDEM 27# include <unistd.h> 28# include <sys/time.h> /* select */ 29# if defined(OPENSSL_TANDEM_FLOSS) 30# include <floss.h(floss_select)> 31# endif 32# elif defined _WIN32 33# include <winsock.h> /* for type fd_set */ 34# else 35# include <unistd.h> 36# if defined __VMS 37# include <sys/socket.h> 38# elif defined _HPUX_SOURCE 39# include <sys/time.h> 40# else 41# include <sys/select.h> 42# endif 43# endif 44 45# ifndef OPENSSL_NO_DEPRECATED_1_1_0 46int BIO_get_host_ip(const char *str, unsigned char *ip) 47{ 48 BIO_ADDRINFO *res = NULL; 49 int ret = 0; 50 51 if (BIO_sock_init() != 1) 52 return 0; /* don't generate another error code here */ 53 54 if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) { 55 size_t l; 56 57 if (BIO_ADDRINFO_family(res) != AF_INET) { 58 ERR_raise(ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); 59 } else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) { 60 /* 61 * Because only AF_INET addresses will reach this far, we can assert 62 * that l should be 4 63 */ 64 if (ossl_assert(l == 4)) 65 ret = BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l); 66 } 67 BIO_ADDRINFO_free(res); 68 } else { 69 ERR_add_error_data(2, "host=", str); 70 } 71 72 return ret; 73} 74 75int BIO_get_port(const char *str, unsigned short *port_ptr) 76{ 77 BIO_ADDRINFO *res = NULL; 78 int ret = 0; 79 80 if (str == NULL) { 81 ERR_raise(ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED); 82 return 0; 83 } 84 85 if (BIO_sock_init() != 1) 86 return 0; /* don't generate another error code here */ 87 88 if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) { 89 if (BIO_ADDRINFO_family(res) != AF_INET) { 90 ERR_raise(ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET); 91 } else { 92 *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res))); 93 ret = 1; 94 } 95 BIO_ADDRINFO_free(res); 96 } else { 97 ERR_add_error_data(2, "host=", str); 98 } 99 100 return ret; 101} 102# endif 103 104int BIO_sock_error(int sock) 105{ 106 int j = 0, i; 107 socklen_t size = sizeof(j); 108 109 /* 110 * Note: under Windows the third parameter is of type (char *) whereas 111 * under other systems it is (void *) if you don't have a cast it will 112 * choke the compiler: if you do have a cast then you can either go for 113 * (char *) or (void *). 114 */ 115 i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size); 116 if (i < 0) 117 return get_last_socket_error(); 118 else 119 return j; 120} 121 122# ifndef OPENSSL_NO_DEPRECATED_1_1_0 123struct hostent *BIO_gethostbyname(const char *name) 124{ 125 /* 126 * Caching gethostbyname() results forever is wrong, so we have to let 127 * the true gethostbyname() worry about this 128 */ 129 return gethostbyname(name); 130} 131# endif 132 133int BIO_sock_init(void) 134{ 135# ifdef OPENSSL_SYS_WINDOWS 136 static struct WSAData wsa_state; 137 138 if (!wsa_init_done) { 139 wsa_init_done = 1; 140 memset(&wsa_state, 0, sizeof(wsa_state)); 141 /* 142 * Not making wsa_state available to the rest of the code is formally 143 * wrong. But the structures we use are [believed to be] invariable 144 * among Winsock DLLs, while API availability is [expected to be] 145 * probed at run-time with DSO_global_lookup. 146 */ 147 if (WSAStartup(0x0202, &wsa_state) != 0) { 148 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), 149 "calling wsastartup()"); 150 ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP); 151 return -1; 152 } 153 } 154# endif /* OPENSSL_SYS_WINDOWS */ 155# ifdef WATT32 156 extern int _watt_do_exit; 157 _watt_do_exit = 0; /* don't make sock_init() call exit() */ 158 if (sock_init()) 159 return -1; 160# endif 161 162 return 1; 163} 164 165void bio_sock_cleanup_int(void) 166{ 167# ifdef OPENSSL_SYS_WINDOWS 168 if (wsa_init_done) { 169 wsa_init_done = 0; 170 WSACleanup(); 171 } 172# endif 173} 174 175int BIO_socket_ioctl(int fd, long type, void *arg) 176{ 177 int i; 178 179# ifdef __DJGPP__ 180 i = ioctlsocket(fd, type, (char *)arg); 181# else 182# if defined(OPENSSL_SYS_VMS) 183 /*- 184 * 2011-02-18 SMS. 185 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we 186 * observe that all the consumers pass in an "unsigned long *", 187 * so we arrange a local copy with a short pointer, and use 188 * that, instead. 189 */ 190# if __INITIAL_POINTER_SIZE == 64 191# define ARG arg_32p 192# pragma pointer_size save 193# pragma pointer_size 32 194 unsigned long arg_32; 195 unsigned long *arg_32p; 196# pragma pointer_size restore 197 arg_32p = &arg_32; 198 arg_32 = *((unsigned long *)arg); 199# else /* __INITIAL_POINTER_SIZE == 64 */ 200# define ARG arg 201# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ 202# else /* defined(OPENSSL_SYS_VMS) */ 203# define ARG arg 204# endif /* defined(OPENSSL_SYS_VMS) [else] */ 205 206 i = ioctlsocket(fd, type, ARG); 207# endif /* __DJGPP__ */ 208 if (i < 0) 209 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), 210 "calling ioctlsocket()"); 211 return i; 212} 213 214# ifndef OPENSSL_NO_DEPRECATED_1_1_0 215int BIO_get_accept_socket(char *host, int bind_mode) 216{ 217 int s = INVALID_SOCKET; 218 char *h = NULL, *p = NULL; 219 BIO_ADDRINFO *res = NULL; 220 221 if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV)) 222 return INVALID_SOCKET; 223 224 if (BIO_sock_init() != 1) 225 return INVALID_SOCKET; 226 227 if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0) 228 goto err; 229 230 if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res), 231 BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) { 232 s = INVALID_SOCKET; 233 goto err; 234 } 235 236 if (!BIO_listen(s, BIO_ADDRINFO_address(res), 237 bind_mode ? BIO_SOCK_REUSEADDR : 0)) { 238 BIO_closesocket(s); 239 s = INVALID_SOCKET; 240 } 241 242 err: 243 BIO_ADDRINFO_free(res); 244 OPENSSL_free(h); 245 OPENSSL_free(p); 246 247 return s; 248} 249 250int BIO_accept(int sock, char **ip_port) 251{ 252 BIO_ADDR res; 253 int ret = -1; 254 255 ret = BIO_accept_ex(sock, &res, 0); 256 if (ret == (int)INVALID_SOCKET) { 257 if (BIO_sock_should_retry(ret)) { 258 ret = -2; 259 goto end; 260 } 261 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), 262 "calling accept()"); 263 ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR); 264 goto end; 265 } 266 267 if (ip_port != NULL) { 268 char *host = BIO_ADDR_hostname_string(&res, 1); 269 char *port = BIO_ADDR_service_string(&res, 1); 270 if (host != NULL && port != NULL) 271 *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2); 272 else 273 *ip_port = NULL; 274 275 if (*ip_port == NULL) { 276 ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); 277 BIO_closesocket(ret); 278 ret = (int)INVALID_SOCKET; 279 } else { 280 strcpy(*ip_port, host); 281 strcat(*ip_port, ":"); 282 strcat(*ip_port, port); 283 } 284 OPENSSL_free(host); 285 OPENSSL_free(port); 286 } 287 288 end: 289 return ret; 290} 291# endif 292 293int BIO_set_tcp_ndelay(int s, int on) 294{ 295 int ret = 0; 296# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) 297 int opt; 298 299# ifdef SOL_TCP 300 opt = SOL_TCP; 301# else 302# ifdef IPPROTO_TCP 303 opt = IPPROTO_TCP; 304# endif 305# endif 306 307 ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); 308# endif 309 return (ret == 0); 310} 311 312int BIO_socket_nbio(int s, int mode) 313{ 314 int ret = -1; 315 int l; 316 317 l = mode; 318# ifdef FIONBIO 319 l = mode; 320 321 ret = BIO_socket_ioctl(s, FIONBIO, &l); 322# elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY)) 323 /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */ 324 325 l = fcntl(s, F_GETFL, 0); 326 if (l == -1) { 327 ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), 328 "calling fcntl()"); 329 ret = -1; 330 } else { 331# if defined(O_NONBLOCK) 332 l &= ~O_NONBLOCK; 333# else 334 l &= ~FNDELAY; /* BSD4.x */ 335# endif 336 if (mode) { 337# if defined(O_NONBLOCK) 338 l |= O_NONBLOCK; 339# else 340 l |= FNDELAY; /* BSD4.x */ 341# endif 342 } 343 ret = fcntl(s, F_SETFL, l); 344 345 if (ret < 0) { 346 ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), 347 "calling fcntl()"); 348 } 349 } 350# else 351 /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */ 352 ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_INVALID_ARGUMENT); 353# endif 354 355 return (ret == 0); 356} 357 358int BIO_sock_info(int sock, 359 enum BIO_sock_info_type type, union BIO_sock_info_u *info) 360{ 361 switch (type) { 362 case BIO_SOCK_INFO_ADDRESS: 363 { 364 socklen_t addr_len; 365 int ret = 0; 366 addr_len = sizeof(*info->addr); 367 ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr), 368 &addr_len); 369 if (ret == -1) { 370 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), 371 "calling getsockname()"); 372 ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR); 373 return 0; 374 } 375 if ((size_t)addr_len > sizeof(*info->addr)) { 376 ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS); 377 return 0; 378 } 379 } 380 break; 381 default: 382 ERR_raise(ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE); 383 return 0; 384 } 385 return 1; 386} 387 388/* 389 * Wait on fd at most until max_time; succeed immediately if max_time == 0. 390 * If for_read == 0 then assume to wait for writing, else wait for reading. 391 * Returns -1 on error, 0 on timeout, and 1 on success. 392 */ 393int BIO_socket_wait(int fd, int for_read, time_t max_time) 394{ 395 fd_set confds; 396 struct timeval tv; 397 time_t now; 398 399 if (fd < 0 || fd >= FD_SETSIZE) 400 return -1; 401 if (max_time == 0) 402 return 1; 403 404 now = time(NULL); 405 if (max_time < now) 406 return 0; 407 408 FD_ZERO(&confds); 409 openssl_fdset(fd, &confds); 410 tv.tv_usec = 0; 411 tv.tv_sec = (long)(max_time - now); /* might overflow */ 412 return select(fd + 1, for_read ? &confds : NULL, 413 for_read ? NULL : &confds, NULL, &tv); 414} 415#endif /* !defined(OPENSSL_NO_SOCK) */ 416