links

lynx-like text mode web browser
git clone anongit@rnpnr.xyz:links.git
Log | Files | Refs | Feed | README | LICENSE

connect.c (20205B)


      1 /* connect.c
      2  * (c) 2002 Mikulas Patocka
      3  * This file is a part of the Links program, released under GPL.
      4  */
      5 
      6 #include <limits.h>
      7 
      8 #include "links.h"
      9 
     10 static void connected(void *);
     11 static void update_dns_priority(struct connection *);
     12 static void connected_callback(struct connection *);
     13 static void dns_found(void *, int);
     14 static void try_connect(struct connection *);
     15 static void handle_socks_reply(void *);
     16 
     17 int
     18 socket_and_bind(int pf, unsigned char *address)
     19 {
     20 	int rs, s = c_socket(pf, SOCK_STREAM, IPPROTO_TCP);
     21 
     22 	if (!address || !(*address))
     23 		return s;
     24 
     25 	switch (pf) {
     26 	case PF_INET: {
     27 		struct sockaddr_in sa;
     28 		unsigned char addr[4];
     29 		if (numeric_ip_address((char *)address, (char *)addr) == -1) {
     30 			EINTRLOOP(rs, close(s));
     31 			errno = EINVAL;
     32 			return -1;
     33 		}
     34 		memset(&sa, 0, sizeof sa);
     35 		sa.sin_family = AF_INET;
     36 		memcpy(&sa.sin_addr.s_addr, addr, 4);
     37 		sa.sin_port = htons(0);
     38 		EINTRLOOP(rs,
     39 		          bind(s, (struct sockaddr *)(void *)&sa, sizeof sa));
     40 		if (rs) {
     41 			int sv_errno = errno;
     42 			EINTRLOOP(rs, close(s));
     43 			errno = sv_errno;
     44 			return -1;
     45 		}
     46 		break;
     47 	}
     48 	case PF_INET6: {
     49 		struct sockaddr_in6 sa;
     50 		unsigned char addr[16];
     51 		unsigned scope;
     52 		if (numeric_ipv6_address((char *)address, (char *)addr, &scope)
     53 		    == -1) {
     54 			EINTRLOOP(rs, close(s));
     55 			errno = EINVAL;
     56 			return -1;
     57 		}
     58 		memset(&sa, 0, sizeof sa);
     59 		sa.sin6_family = AF_INET6;
     60 		memcpy(&sa.sin6_addr, addr, 16);
     61 		sa.sin6_port = htons(0);
     62 		sa.sin6_scope_id = scope;
     63 		EINTRLOOP(rs,
     64 		          bind(s, (struct sockaddr *)(void *)&sa, sizeof sa));
     65 		if (rs) {
     66 			int sv_errno = errno;
     67 			EINTRLOOP(rs, close(s));
     68 			errno = sv_errno;
     69 			return -1;
     70 		}
     71 		break;
     72 	}
     73 	default:
     74 		EINTRLOOP(rs, close(s));
     75 		errno = EINVAL;
     76 		return -1;
     77 	}
     78 
     79 	return s;
     80 }
     81 
     82 void
     83 close_socket(int *s)
     84 {
     85 	int rs;
     86 	if (*s == -1)
     87 		return;
     88 	set_handlers(*s, NULL, NULL, NULL);
     89 	EINTRLOOP(rs, close(*s));
     90 	*s = -1;
     91 }
     92 
     93 struct conn_info {
     94 	void (*func)(struct connection *);
     95 	struct lookup_state l;
     96 	int first_error;
     97 	int *sock;
     98 	int socks_byte_count;
     99 	int socks_handled;
    100 	unsigned char socks_reply[8];
    101 	char host[1];
    102 };
    103 
    104 void
    105 make_connection(struct connection *c, int port, int *sock,
    106                 void (*func)(struct connection *))
    107 {
    108 	int socks_port = -1;
    109 	int as;
    110 	char *p, *host;
    111 	size_t sl;
    112 	struct conn_info *b;
    113 	if (*c->socks_proxy) {
    114 		p = strchr(c->socks_proxy, '@');
    115 		if (p)
    116 			p++;
    117 		else
    118 			p = c->socks_proxy;
    119 		host = strdup(p);
    120 		socks_port = 1080;
    121 		if ((p = strchr(host, ':'))) {
    122 			long lp;
    123 			*p++ = 0;
    124 			if (!*p)
    125 				goto badu;
    126 			lp = strtol(p, &p, 10);
    127 			if (*p || lp <= 0 || lp >= 65536) {
    128 badu:
    129 				free(host);
    130 				setcstate(c, S_BAD_URL);
    131 				abort_connection(c);
    132 				return;
    133 			}
    134 			socks_port = (int)lp;
    135 		}
    136 	} else if (!(host = (char *)get_host_name(c->url))) {
    137 		setcstate(c, S_INTERNAL);
    138 		abort_connection(c);
    139 		return;
    140 	}
    141 	if (c->newconn)
    142 		internal("already making a connection");
    143 	sl = strlen(host);
    144 	if (sl > INT_MAX - sizeof(struct conn_info))
    145 		overalloc();
    146 	b = mem_calloc(sizeof(struct conn_info) + sl);
    147 	b->func = func;
    148 	b->sock = sock;
    149 	b->l.socks_port = socks_port;
    150 	b->l.target_port = port;
    151 	strcpy(b->host, host);
    152 	c->newconn = b;
    153 	if (c->last_lookup_state.addr_index < c->last_lookup_state.addr.n) {
    154 		b->l.addr = c->last_lookup_state.addr;
    155 		b->l.addr_index = c->last_lookup_state.addr_index;
    156 		b->l.dont_try_more_servers = 1;
    157 		dns_found(c, 0);
    158 		as = 0;
    159 	} else if (c->no_cache >= NC_RELOAD)
    160 		as = find_host_no_cache(host, &b->l.addr, &c->dnsquery,
    161 		                        dns_found, c);
    162 	else
    163 		as = find_host(host, &b->l.addr, &c->dnsquery, dns_found, c);
    164 	free(host);
    165 	if (as)
    166 		setcstate(c, S_DNS);
    167 }
    168 
    169 static void
    170 ssl_setup_downgrade(struct connection *c)
    171 {
    172 #if !defined(HAVE_NSS)
    173 	int dd = c->no_tls;
    174 	#ifdef SSL_OP_NO_TLSv1_3
    175 	if (dd) {
    176 		SSL_set_options(c->ssl->ssl, SSL_OP_NO_TLSv1_3);
    177 		dd--;
    178 	}
    179 	#endif
    180 	#ifdef SSL_OP_NO_TLSv1_2
    181 	if (dd) {
    182 		SSL_set_options(c->ssl->ssl, SSL_OP_NO_TLSv1_2);
    183 		dd--;
    184 	}
    185 	#endif
    186 	#ifdef SSL_OP_NO_TLSv1_1
    187 	if (dd) {
    188 		SSL_set_options(c->ssl->ssl, SSL_OP_NO_TLSv1_1);
    189 		dd--;
    190 	}
    191 	#endif
    192 	#ifdef SSL_OP_NO_TLSv1
    193 	if (dd) {
    194 		SSL_set_options(c->ssl->ssl, SSL_OP_NO_TLSv1);
    195 		dd--;
    196 	}
    197 	#endif
    198 	#ifdef SSL_MODE_SEND_FALLBACK_SCSV
    199 	if (dd != c->no_tls) {
    200 		SSL_set_mode(c->ssl->ssl, SSL_MODE_SEND_FALLBACK_SCSV);
    201 	}
    202 	#endif
    203 	if (SCRUB_HEADERS) {
    204 	#ifdef SSL_OP_NO_SSLv2
    205 		SSL_set_options(c->ssl->ssl, SSL_OP_NO_SSLv2);
    206 	#endif
    207 	#ifdef SSL_OP_NO_SSLv3
    208 		SSL_set_options(c->ssl->ssl, SSL_OP_NO_SSLv3);
    209 	#endif
    210 	}
    211 #endif
    212 }
    213 
    214 static void
    215 ssl_downgrade_dance(struct connection *c)
    216 {
    217 #if !defined(HAVE_NSS)
    218 	int downgrades = 0;
    219 	c->no_ssl_session = 1;
    220 	if (c->ssl && c->ssl->session_set) {
    221 		retry_connect(c, S_SSL_ERROR, 1);
    222 		return;
    223 	}
    224 	#ifdef SSL_OP_NO_TLSv1_3
    225 	downgrades++;
    226 	#endif
    227 	#ifdef SSL_OP_NO_TLSv1_2
    228 	downgrades++;
    229 	#endif
    230 	#ifdef SSL_OP_NO_TLSv1_1
    231 	downgrades++;
    232 	#endif
    233 	#ifdef SSL_OP_NO_TLSv1
    234 	downgrades++;
    235 	#endif
    236 	if (++c->no_tls <= downgrades) {
    237 		retry_connect(c, S_SSL_ERROR, 1);
    238 	} else {
    239 		c->no_tls = 0;
    240 		retry_connect(c, S_SSL_ERROR, 0);
    241 	}
    242 #else
    243 	retry_connect(c, S_SSL_ERROR, 0);
    244 #endif
    245 }
    246 
    247 static void
    248 ssl_want_io(void *c_)
    249 {
    250 	struct connection *c = (struct connection *)c_;
    251 	struct conn_info *b = c->newconn;
    252 
    253 	set_connection_timeout(c);
    254 
    255 	switch (SSL_get_error(c->ssl->ssl, SSL_connect(c->ssl->ssl))) {
    256 	case SSL_ERROR_NONE:
    257 		connected_callback(c);
    258 		break;
    259 	case SSL_ERROR_WANT_READ:
    260 		set_handlers(*b->sock, ssl_want_io, NULL, c);
    261 		break;
    262 	case SSL_ERROR_WANT_WRITE:
    263 		set_handlers(*b->sock, NULL, ssl_want_io, c);
    264 		break;
    265 	default:
    266 		ssl_downgrade_dance(c);
    267 	}
    268 }
    269 
    270 static void
    271 handle_socks(void *c_)
    272 {
    273 	struct connection *c = (struct connection *)c_;
    274 	struct conn_info *b = c->newconn;
    275 	unsigned char *command = NULL;
    276 	size_t len;
    277 	unsigned char *host;
    278 	int wr;
    279 	setcstate(c, S_SOCKS_NEG);
    280 	set_connection_timeout(c);
    281 	len = add_bytes_to_str(&command, 0, cast_uchar "\004\001", 2);
    282 	len = add_chr_to_str(&command, len, b->l.target_port >> 8);
    283 	len = add_chr_to_str(&command, len, b->l.target_port);
    284 	len = add_bytes_to_str(&command, len, cast_uchar "\000\000\000\001", 4);
    285 	if (strchr(c->socks_proxy, '@'))
    286 		len = add_bytes_to_str(&command, len,
    287 		                       (unsigned char *)c->socks_proxy,
    288 		                       strcspn(c->socks_proxy, "@"));
    289 	len = add_chr_to_str(&command, len, 0);
    290 	if (!(host = get_host_name(c->url))) {
    291 		free(command);
    292 		setcstate(c, S_INTERNAL);
    293 		abort_connection(c);
    294 		return;
    295 	}
    296 	len = add_to_str(&command, len, host);
    297 	len = add_to_str(&command, len, c->dns_append);
    298 	len = add_chr_to_str(&command, len, 0);
    299 	free(host);
    300 	if (b->socks_byte_count >= len) {
    301 		free(command);
    302 		setcstate(c, S_MODIFIED);
    303 		retry_connection(c);
    304 		return;
    305 	}
    306 	EINTRLOOP(wr, (int)write(*b->sock, command + b->socks_byte_count,
    307 	                         len - b->socks_byte_count));
    308 	free(command);
    309 	if (wr <= 0) {
    310 		setcstate(c, wr ? get_error_from_errno(errno) : S_CANT_WRITE);
    311 		retry_connection(c);
    312 		return;
    313 	}
    314 	b->socks_byte_count += wr;
    315 	if (b->socks_byte_count < len) {
    316 		set_handlers(*b->sock, NULL, handle_socks, c);
    317 		return;
    318 	} else {
    319 		b->socks_byte_count = 0;
    320 		set_handlers(*b->sock, handle_socks_reply, NULL, c);
    321 		return;
    322 	}
    323 }
    324 
    325 static void
    326 handle_socks_reply(void *c_)
    327 {
    328 	struct connection *c = (struct connection *)c_;
    329 	struct conn_info *b = c->newconn;
    330 	int rd;
    331 	set_connection_timeout(c);
    332 	EINTRLOOP(rd, (int)read(*b->sock, b->socks_reply + b->socks_byte_count,
    333 	                        sizeof b->socks_reply - b->socks_byte_count));
    334 	if (rd <= 0) {
    335 		setcstate(c, rd ? get_error_from_errno(errno) : S_CANT_READ);
    336 		retry_connection(c);
    337 		return;
    338 	}
    339 	b->socks_byte_count += rd;
    340 	if (b->socks_byte_count < (int)sizeof b->socks_reply)
    341 		return;
    342 	if (b->socks_reply[0]) {
    343 		setcstate(c, S_BAD_SOCKS_VERSION);
    344 		abort_connection(c);
    345 		return;
    346 	}
    347 	switch (b->socks_reply[1]) {
    348 	case 91:
    349 		setcstate(c, S_SOCKS_REJECTED);
    350 		retry_connection(c);
    351 		return;
    352 	case 92:
    353 		setcstate(c, S_SOCKS_NO_IDENTD);
    354 		abort_connection(c);
    355 		return;
    356 	case 93:
    357 		setcstate(c, S_SOCKS_BAD_USERID);
    358 		abort_connection(c);
    359 		return;
    360 	default:
    361 		setcstate(c, S_SOCKS_UNKNOWN_ERROR);
    362 		retry_connection(c);
    363 		return;
    364 	case 90:
    365 		break;
    366 	}
    367 	connected(c);
    368 }
    369 
    370 static void
    371 dns_found(void *c_, int state)
    372 {
    373 	struct connection *c = (struct connection *)c_;
    374 	if (state) {
    375 		setcstate(c, *c->socks_proxy || is_proxy_url(c->url)
    376 		                 ? S_NO_PROXY_DNS
    377 		                 : S_NO_DNS);
    378 		abort_connection(c);
    379 		return;
    380 	}
    381 	try_connect(c);
    382 }
    383 
    384 void
    385 retry_connect(struct connection *c, int err, int ssl_downgrade)
    386 {
    387 	struct conn_info *b = c->newconn;
    388 	if (!b->l.addr_index)
    389 		b->first_error = err;
    390 	freeSSL(c->ssl);
    391 	c->ssl = NULL;
    392 	if (ssl_downgrade) {
    393 		close_socket(b->sock);
    394 		try_connect(c);
    395 		return;
    396 	}
    397 	b->l.addr_index++;
    398 #if MAX_ADDRESSES > 1
    399 	if (b->l.addr_index < b->l.addr.n && !b->l.dont_try_more_servers) {
    400 		if (b->l.addr_index == 1)
    401 			rotate_addresses(&b->l.addr);
    402 		close_socket(b->sock);
    403 		try_connect(c);
    404 	} else
    405 #endif
    406 	{
    407 		dns_clear_host(b->host);
    408 		setcstate(c, b->first_error);
    409 		retry_connection(c);
    410 	}
    411 }
    412 
    413 static void
    414 try_connect(struct connection *c)
    415 {
    416 	int s;
    417 	int rs;
    418 	unsigned short p;
    419 	struct conn_info *b = c->newconn;
    420 	struct host_address *addr = &b->l.addr.a[b->l.addr_index];
    421 	if (addr->af == AF_INET)
    422 		s = socket_and_bind(PF_INET, bind_ip_address);
    423 	else if (addr->af == AF_INET6)
    424 		s = socket_and_bind(PF_INET6, bind_ipv6_address);
    425 	else {
    426 		setcstate(c, S_INTERNAL);
    427 		abort_connection(c);
    428 		return;
    429 	}
    430 	if (s == -1) {
    431 		retry_connect(c, get_error_from_errno(errno), 0);
    432 		return;
    433 	}
    434 	set_nonblock(s);
    435 	*b->sock = s;
    436 	b->socks_handled = 0;
    437 	b->socks_byte_count = 0;
    438 	p = b->l.socks_port != -1 ? b->l.socks_port : b->l.target_port;
    439 	if (addr->af == AF_INET) {
    440 		struct sockaddr_in sa;
    441 		memset(&sa, 0, sizeof sa);
    442 		sa.sin_family = AF_INET;
    443 		memcpy(&sa.sin_addr.s_addr, addr->addr, 4);
    444 		sa.sin_port = htons(p);
    445 		EINTRLOOP(
    446 		    rs, connect(s, (struct sockaddr *)(void *)&sa, sizeof sa));
    447 	} else if (addr->af == AF_INET6) {
    448 		struct sockaddr_in6 sa;
    449 		memset(&sa, 0, sizeof sa);
    450 		sa.sin6_family = AF_INET6;
    451 		memcpy(&sa.sin6_addr, addr->addr, 16);
    452 		sa.sin6_scope_id = addr->scope_id;
    453 		sa.sin6_port = htons(p);
    454 		EINTRLOOP(
    455 		    rs, connect(s, (struct sockaddr *)(void *)&sa, sizeof sa));
    456 	} else {
    457 		rs = -1;
    458 		errno = EINVAL;
    459 	}
    460 	if (rs) {
    461 		if (errno != EALREADY && errno != EINPROGRESS) {
    462 			retry_connect(c, get_error_from_errno(errno), 0);
    463 			return;
    464 		}
    465 		set_handlers(s, NULL, connected, c);
    466 		setcstate(c, !b->l.addr_index ? S_CONN : S_CONN_ANOTHER);
    467 #if MAX_ADDRESSES > 1
    468 		if (b->l.addr.n > 1
    469 		    && (is_connection_restartable(c) || max_tries == 1)) {
    470 			set_connection_timeout(c);
    471 		}
    472 #endif
    473 	} else {
    474 		connected(c);
    475 	}
    476 }
    477 
    478 void
    479 continue_connection(struct connection *c, int *sock,
    480                     void (*func)(struct connection *))
    481 {
    482 	struct conn_info *b;
    483 	if (c->newconn)
    484 		internal("already making a connection");
    485 	b = mem_calloc(sizeof(struct conn_info));
    486 	b->func = func;
    487 	b->sock = sock;
    488 	b->l = c->last_lookup_state;
    489 	b->socks_handled = 1;
    490 	c->newconn = b;
    491 	connected(c);
    492 }
    493 
    494 static void
    495 connected(void *c_)
    496 {
    497 	struct connection *c = (struct connection *)c_;
    498 	struct conn_info *b = c->newconn;
    499 #ifdef SO_ERROR
    500 	int err = 0;
    501 	socklen_t len = sizeof(int);
    502 	int rs;
    503 #endif
    504 	clear_connection_timeout(c);
    505 #ifdef SO_ERROR
    506 	errno = 0;
    507 	EINTRLOOP(
    508 	    rs, getsockopt(*b->sock, SOL_SOCKET, SO_ERROR, (void *)&err, &len));
    509 	if (!rs) {
    510 		if (err >= 10000)
    511 			err -= 10000; /* Why does EMX return so large values? */
    512 	} else {
    513 		if (!(err = errno)) {
    514 			retry_connect(c, S_STATE, 0);
    515 			return;
    516 		}
    517 	}
    518 	if (err > 0
    519 	#ifdef EISCONN
    520 	    && err != EISCONN
    521 	#endif
    522 	) {
    523 		retry_connect(c, get_error_from_errno(err), 0);
    524 		return;
    525 	}
    526 #endif
    527 	set_connection_timeout(c);
    528 	if (b->l.socks_port != -1 && !b->socks_handled) {
    529 		b->socks_handled = 1;
    530 		update_dns_priority(c);
    531 		handle_socks(c);
    532 		return;
    533 	}
    534 	if (c->ssl) {
    535 		unsigned char *orig_url = remove_proxy_prefix(c->url);
    536 		unsigned char *h = get_host_name(orig_url);
    537 		if (*h && h[strlen(cast_const_char h) - 1] == '.')
    538 			h[strlen(cast_const_char h) - 1] = 0;
    539 		c->ssl = getSSL();
    540 		if (!c->ssl) {
    541 			free(h);
    542 			goto ssl_error;
    543 		}
    544 		if (!proxies.only_proxies && !c->no_ssl_session) {
    545 			unsigned char *h = get_host_name(orig_url);
    546 			int p = get_port(orig_url);
    547 			SSL_SESSION *ses =
    548 			    get_session_cache_entry(c->ssl->ctx, h, p);
    549 			if (ses) {
    550 				if (SSL_set_session(c->ssl->ssl, ses) == 1)
    551 					c->ssl->session_set = 1;
    552 			}
    553 			free(h);
    554 		}
    555 #if !defined(OPENSSL_NO_STDIO)
    556 		if (!proxies.only_proxies) {
    557 			if (ssl_options.client_cert_key[0]) {
    558 				SSL_use_PrivateKey_file(
    559 				    c->ssl->ssl,
    560 				    cast_const_char ssl_options.client_cert_key,
    561 				    SSL_FILETYPE_PEM);
    562 			}
    563 			if (ssl_options.client_cert_crt[0]) {
    564 				SSL_use_certificate_file(
    565 				    c->ssl->ssl,
    566 				    cast_const_char ssl_options.client_cert_crt,
    567 				    SSL_FILETYPE_PEM);
    568 			}
    569 		}
    570 #endif
    571 		SSL_set_fd(c->ssl->ssl, *b->sock);
    572 		ssl_setup_downgrade(c);
    573 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
    574 		if (h[0] == '[' || !numeric_ip_address((char *)h, NULL)
    575 		    || !numeric_ipv6_address((char *)h, NULL, NULL))
    576 			goto skip_numeric_address;
    577 		SSL_set_tlsext_host_name(c->ssl->ssl, h);
    578 skip_numeric_address:
    579 #endif
    580 		free(h);
    581 		switch (SSL_get_error(c->ssl->ssl, SSL_connect(c->ssl->ssl))) {
    582 		case SSL_ERROR_WANT_READ:
    583 			setcstate(c, S_SSL_NEG);
    584 			set_handlers(*b->sock, ssl_want_io, NULL, c);
    585 			return;
    586 		case SSL_ERROR_WANT_WRITE:
    587 			setcstate(c, S_SSL_NEG);
    588 			set_handlers(*b->sock, NULL, ssl_want_io, c);
    589 			return;
    590 		case SSL_ERROR_NONE:
    591 			break;
    592 		default:
    593 ssl_error:
    594 			ssl_downgrade_dance(c);
    595 			return;
    596 		}
    597 	}
    598 	connected_callback(c);
    599 }
    600 
    601 static void
    602 update_dns_priority(struct connection *c)
    603 {
    604 #if MAX_ADDRESSES > 1
    605 	struct conn_info *b = c->newconn;
    606 	if (!b->l.dont_try_more_servers && b->host[0]) {
    607 		if (b->l.addr_index) {
    608 			int i;
    609 			for (i = 0; i < b->l.addr_index; i++)
    610 				dns_set_priority(b->host, &b->l.addr.a[i], 0);
    611 			dns_set_priority(b->host, &b->l.addr.a[i], 1);
    612 		}
    613 		b->l.dont_try_more_servers = 1;
    614 	}
    615 #endif
    616 }
    617 
    618 static void
    619 connected_callback(struct connection *c)
    620 {
    621 	int flags;
    622 	struct conn_info *b = c->newconn;
    623 	update_dns_priority(c);
    624 	if (c->ssl) {
    625 		if (ssl_options.certificates
    626 		    != SSL_ACCEPT_INVALID_CERTIFICATE) {
    627 			unsigned char *h =
    628 			    get_host_name(remove_proxy_prefix(c->url));
    629 			int err = verify_ssl_certificate(c->ssl, h);
    630 			if (err) {
    631 				if (ssl_options.certificates
    632 				    == SSL_WARN_ON_INVALID_CERTIFICATE) {
    633 					flags = get_blacklist_flags(h);
    634 					if (flags & BL_IGNORE_CERTIFICATE)
    635 						goto ignore_cert;
    636 				}
    637 				free(h);
    638 				setcstate(c, err);
    639 				abort_connection(c);
    640 				return;
    641 			}
    642 ignore_cert:
    643 
    644 			if (c->no_tls) {
    645 				if (ssl_options.certificates
    646 				    == SSL_WARN_ON_INVALID_CERTIFICATE) {
    647 					flags = get_blacklist_flags(h);
    648 					if (flags & BL_IGNORE_DOWNGRADE)
    649 						goto ignore_downgrade;
    650 				}
    651 				free(h);
    652 				setcstate(c, S_DOWNGRADED_METHOD);
    653 				abort_connection(c);
    654 				return;
    655 			}
    656 ignore_downgrade:
    657 
    658 			err = verify_ssl_cipher(c->ssl);
    659 			if (err) {
    660 				if (ssl_options.certificates
    661 				    == SSL_WARN_ON_INVALID_CERTIFICATE) {
    662 					flags = get_blacklist_flags(h);
    663 					if (flags & BL_IGNORE_CIPHER)
    664 						goto ignore_cipher;
    665 				}
    666 				free(h);
    667 				setcstate(c, err);
    668 				abort_connection(c);
    669 				return;
    670 			}
    671 ignore_cipher:
    672 
    673 			free(h);
    674 		}
    675 	}
    676 	retrieve_ssl_session(c);
    677 	c->last_lookup_state = b->l;
    678 	c->newconn = NULL;
    679 	b->func(c);
    680 	free(b);
    681 }
    682 
    683 struct write_buffer {
    684 	int sock;
    685 	int len;
    686 	int pos;
    687 	void (*done)(struct connection *);
    688 	unsigned char data[1];
    689 };
    690 
    691 static void
    692 write_select(void *c_)
    693 {
    694 	struct connection *c = (struct connection *)c_;
    695 	struct write_buffer *wb;
    696 	int wr;
    697 	if (!(wb = c->buffer)) {
    698 		internal("write socket has no buffer");
    699 		setcstate(c, S_INTERNAL);
    700 		abort_connection(c);
    701 		return;
    702 	}
    703 	if (wb->pos)
    704 		set_connection_timeout(c);
    705 	else
    706 		set_connection_timeout_keepal(c);
    707 
    708 	if (c->ssl) {
    709 		set_handlers(wb->sock, NULL, write_select, c);
    710 		if ((wr = SSL_write(c->ssl->ssl, (void *)(wb->data + wb->pos),
    711 		                    wb->len - wb->pos))
    712 		    <= 0) {
    713 			int err;
    714 			err = SSL_get_error(c->ssl->ssl, wr);
    715 			if (err == SSL_ERROR_WANT_WRITE) {
    716 				return;
    717 			}
    718 			if (err == SSL_ERROR_WANT_READ) {
    719 				set_handlers(wb->sock, write_select, NULL, c);
    720 				return;
    721 			}
    722 			setcstate(c, wr ? (err == SSL_ERROR_SYSCALL
    723 			                       ? get_error_from_errno(errno)
    724 			                       : S_SSL_ERROR)
    725 			                : S_CANT_WRITE);
    726 			if (!wr || err == SSL_ERROR_SYSCALL)
    727 				retry_connection(c);
    728 			else
    729 				abort_connection(c);
    730 			return;
    731 		}
    732 		c->ssl->bytes_written += wr;
    733 	} else {
    734 		EINTRLOOP(wr, (int)write(wb->sock, wb->data + wb->pos,
    735 		                         wb->len - wb->pos));
    736 		if (wr <= 0) {
    737 			setcstate(c, wr ? get_error_from_errno(errno)
    738 			                : S_CANT_WRITE);
    739 			retry_connection(c);
    740 			return;
    741 		}
    742 	}
    743 
    744 	if ((wb->pos += wr) == wb->len) {
    745 		void (*f)(struct connection *) = wb->done;
    746 		c->buffer = NULL;
    747 		set_handlers(wb->sock, NULL, NULL, NULL);
    748 		free(wb);
    749 		f(c);
    750 	}
    751 }
    752 
    753 void
    754 write_to_socket(struct connection *c, int s, unsigned char *data, int len,
    755                 void (*write_func)(struct connection *))
    756 {
    757 	struct write_buffer *wb;
    758 	if ((unsigned)len > INT_MAX - sizeof(struct write_buffer))
    759 		overalloc();
    760 	wb = xmalloc(sizeof(struct write_buffer) + len);
    761 	wb->sock = s;
    762 	wb->len = len;
    763 	wb->pos = 0;
    764 	wb->done = write_func;
    765 	memcpy(wb->data, data, len);
    766 	free(c->buffer);
    767 	c->buffer = wb;
    768 	set_handlers(s, NULL, write_select, c);
    769 }
    770 
    771 #define READ_SIZE  64240
    772 #define TOTAL_READ (4193008 - READ_SIZE)
    773 
    774 static void
    775 read_select(void *c_)
    776 {
    777 	struct connection *c = (struct connection *)c_;
    778 	int total_read = 0;
    779 	struct read_buffer *rb;
    780 	int rd;
    781 	if (!(rb = c->buffer)) {
    782 		internal("read socket has no buffer");
    783 		setcstate(c, S_INTERNAL);
    784 		abort_connection(c);
    785 		return;
    786 	}
    787 	set_handlers(rb->sock, NULL, NULL, NULL);
    788 
    789 read_more:
    790 	if ((unsigned)rb->len
    791 	    > INT_MAX - sizeof(struct read_buffer) - READ_SIZE)
    792 		overalloc();
    793 	rb = xrealloc(rb, sizeof(struct read_buffer) + rb->len + READ_SIZE);
    794 	c->buffer = rb;
    795 
    796 	if (c->ssl) {
    797 		if ((rd = SSL_read(c->ssl->ssl, (void *)(rb->data + rb->len),
    798 		                   READ_SIZE))
    799 		    <= 0) {
    800 			int err;
    801 			if (total_read)
    802 				goto success;
    803 			err = SSL_get_error(c->ssl->ssl, rd);
    804 			if (err == SSL_ERROR_WANT_READ) {
    805 				set_handlers(rb->sock, read_select, NULL, c);
    806 				return;
    807 			}
    808 			if (err == SSL_ERROR_WANT_WRITE) {
    809 				set_handlers(rb->sock, NULL, read_select, c);
    810 				return;
    811 			}
    812 			if (rb->close && !rd) {
    813 				rb->close = 2;
    814 				rb->done(c, rb);
    815 				return;
    816 			}
    817 			setcstate(c, rd ? (err == SSL_ERROR_SYSCALL
    818 			                       ? get_error_from_errno(errno)
    819 			                       : S_SSL_ERROR)
    820 			                : S_CANT_READ);
    821 			if (!rd || err == SSL_ERROR_SYSCALL)
    822 				retry_connection(c);
    823 			else
    824 				abort_connection(c);
    825 			return;
    826 		}
    827 		c->ssl->bytes_read += rd;
    828 	} else {
    829 		EINTRLOOP(rd,
    830 		          (int)read(rb->sock, rb->data + rb->len, READ_SIZE));
    831 		if (rd <= 0) {
    832 			if (total_read)
    833 				goto success;
    834 			if (rb->close && !rd) {
    835 				rb->close = 2;
    836 				rb->done(c, rb);
    837 				return;
    838 			}
    839 			setcstate(c, rd ? get_error_from_errno(errno)
    840 			                : S_CANT_READ);
    841 			retry_connection(c);
    842 			return;
    843 		}
    844 	}
    845 	rb->len += rd;
    846 	total_read += rd;
    847 
    848 	if ((rd == READ_SIZE || c->ssl) && total_read <= TOTAL_READ) {
    849 		if (can_read(rb->sock))
    850 			goto read_more;
    851 	}
    852 success:
    853 	retrieve_ssl_session(c);
    854 	rb->done(c, rb);
    855 }
    856 
    857 struct read_buffer *
    858 alloc_read_buffer(void)
    859 {
    860 	struct read_buffer *rb;
    861 	rb = xmalloc(sizeof(struct read_buffer) + READ_SIZE);
    862 	memset(rb, 0, sizeof(struct read_buffer) + READ_SIZE);
    863 	return rb;
    864 }
    865 
    866 void
    867 read_from_socket(struct connection *c, int s, struct read_buffer *buf,
    868                  void (*read_func)(struct connection *, struct read_buffer *))
    869 {
    870 	buf->done = read_func;
    871 	buf->sock = s;
    872 	if (buf != c->buffer)
    873 		free(c->buffer);
    874 	c->buffer = buf;
    875 	set_handlers(s, read_select, NULL, c);
    876 }
    877 
    878 void
    879 kill_buffer_data(struct read_buffer *rb, int n)
    880 {
    881 	if (n > rb->len || n < 0) {
    882 		internal("called kill_buffer_data with bad value");
    883 		rb->len = 0;
    884 		return;
    885 	}
    886 	memmove(rb->data, rb->data + n, rb->len - n);
    887 	rb->len -= n;
    888 }