}
#endif
- if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), BIO_SOCK_NODELAY)) {
+ if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai),
+ protocol == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) {
BIO_closesocket(*sock);
*sock = INVALID_SOCKET;
continue;
int i;
BIO_ADDRINFO *res = NULL;
const BIO_ADDRINFO *next;
- int sock_family, sock_type, sock_protocol;
+ int sock_family, sock_type, sock_protocol, sock_port;
const BIO_ADDR *sock_address;
int sock_options = BIO_SOCK_REUSEADDR;
int ret = 0;
}
#endif
+ sock_port = BIO_ADDR_rawport(sock_address);
+
BIO_ADDRINFO_free(res);
res = NULL;
- {
+ if (sock_port == 0) {
+ /* dynamically allocated port, report which one */
union BIO_sock_info_u info;
char *hostname = NULL;
char *service = NULL;
ERR_print_errors(bio_err);
goto end;
}
+ } else {
+ (void)BIO_printf(bio_s_out, "ACCEPT\n");
+ (void)BIO_flush(bio_s_out);
}
if (accept_sock != NULL)
*accept_sock = asock;
for (;;) {
+ char sink[64];
+ struct timeval timeout;
+ fd_set readfds;
+
if (type == SOCK_STREAM) {
BIO_ADDR_free(ourpeer);
ourpeer = BIO_ADDR_new();
* TCP-RST. This seems to allow the peer to read the alert data.
*/
shutdown(sock, 1); /* SHUT_WR */
+ /*
+ * We just said we have nothing else to say, but it doesn't mean
+ * that the other side has nothing. It's even recommended to
+ * consume incoming data. [In testing context this ensures that
+ * alerts are passed on...]
+ */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500000; /* some extreme round-trip */
+ do {
+ FD_ZERO(&readfds);
+ openssl_fdset(sock, &readfds);
+ } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
+ && readsocket(sock, sink, sizeof(sink)) > 0);
+
BIO_closesocket(sock);
} else {
i = (*cb)(asock, type, protocol, context);