DECLARE_TEST(tcp, blocking) { socket_t* sock = tcp_socket_allocate(); socket_set_blocking(sock, false); EXPECT_FALSE(socket_blocking(sock)); socket_set_blocking(sock, true); EXPECT_TRUE(socket_blocking(sock)); socket_deallocate(sock); return 0; }
static int wait_for_client(int port) { struct sockaddr_in sin; socklen_t addrlen; int listenfd; int clientfd; Octstr *addr; listenfd = make_server_socket(port, NULL); if (listenfd < 0) { fprintf(stderr, "%s: failed to open socket at port %d\n", progname, port); exit(1); } do { addrlen = sizeof(sin); clientfd = accept(listenfd, (struct sockaddr *)&sin, &addrlen); if (clientfd < 0) { error(errno, "failed to accept new connection"); } } while (clientfd < 0); if (socket_set_blocking(clientfd, 0) < 0) { panic(0, "failed to make client socket nonblocking"); } addr = gw_netaddr_to_octstr(AF_INET, &sin.sin_addr); info(0, "Accepted client from %s:%d", octstr_get_cstr(addr), ntohs(sin.sin_port)); octstr_destroy(addr); close(listenfd); return clientfd; }
static int ois_open_listener(SMSCenter *smsc) { SAY(2, "ois_open_listener"); smsc->ois_listening_socket = make_server_socket(smsc->receive_port, NULL); /* XXX add interface_name if required */ if (smsc->ois_listening_socket < 0) { goto error; } if (socket_set_blocking(smsc->ois_listening_socket, 0) < 0) { ois_close(smsc); goto error; } smsc->ois_flags &= ~OIS_FLAG_ERROR; smsc->ois_flags &= ~OIS_FLAG_NOBANNER; smsc->ois_alive2 = time(&smsc->ois_alive); SAY2(2, "ois_open_listener fd=%d", smsc->ois_listening_socket); return 0; error: error(0, "ois_open_listener: failed to open listening socket"); return -1; }
/* * XXX bad assumption here that conn_wrap_fd for SSL can only happens * for the server side!!!! FIXME !!!! */ Connection *conn_wrap_fd(int fd, int ssl) { Connection *conn; if (socket_set_blocking(fd, 0) < 0) return NULL; conn = gw_malloc(sizeof(*conn)); conn->inlock = mutex_create(); conn->outlock = mutex_create(); conn->claimed = 0; conn->outbuf = octstr_create(""); conn->outbufpos = 0; conn->inbuf = octstr_create(""); conn->inbufpos = 0; conn->fd = fd; conn->connected = yes; conn->read_eof = 0; conn->io_error = 0; conn->output_buffering = DEFAULT_OUTPUT_BUFFERING; conn->registered = NULL; conn->callback = NULL; conn->callback_data = NULL; conn->callback_data_destroyer = NULL; conn->listening_pollin = 0; conn->listening_pollout = 0; #ifdef HAVE_LIBSSL /* * do all the SSL magic for this connection */ if (ssl) { conn->ssl = SSL_new(global_server_ssl_context); conn->peer_certificate = NULL; /* SSL_set_fd can fail, so check it */ if (SSL_set_fd(conn->ssl, conn->fd) == 0) { /* SSL_set_fd failed, log error and return NULL */ error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL)); conn_destroy(conn); return NULL; } /* SSL_set_verify(conn->ssl, 0, NULL); */ /* set read/write BIO layer to non-blocking mode */ BIO_set_nbio(SSL_get_rbio(conn->ssl), 1); BIO_set_nbio(SSL_get_wbio(conn->ssl), 1); /* set accept state , SSL-Handshake will be handled transparent while SSL_[read|write] */ SSL_set_accept_state(conn->ssl); } else { conn->ssl = NULL; conn->peer_certificate = NULL; } #endif /* HAVE_LIBSSL */ return conn; }
/* Allocate and fill a threadinfo structure for a new thread, and store * it in a free slot in the thread table. The thread table must already * be locked by the caller. Return the thread number chosen for this * thread. The caller must make sure that there is room in the table. */ static long fill_threadinfo(pthread_t id, const char *name, gwthread_func_t *func, struct threadinfo *ti) { int pipefds[2]; long first_try; gw_assert(active_threads < THREADTABLE_SIZE); /* initialize to default values */ ti->self = id; ti->name = name; ti->func = func; ti->pid = -1; ti->wakefd_recv = -1; ti->wakefd_send = -1; ti->joiners = NULL; ti->number = -1; if (pipe(pipefds) < 0) { error(errno, "cannot allocate wakeup pipe for new thread"); return -1; } ti->wakefd_recv = pipefds[0]; ti->wakefd_send = pipefds[1]; socket_set_blocking(ti->wakefd_recv, 0); socket_set_blocking(ti->wakefd_send, 0); /* Find a free table entry and claim it. */ first_try = next_threadnumber; do { ti->number = next_threadnumber++; /* Check if we looped all the way around the thread table. */ if (ti->number == first_try + THREADTABLE_SIZE) { error(0, "Cannot have more than %d active threads", THREADTABLE_SIZE); ti->number = -1; return -1; } } while (THREAD(ti->number) != NULL); THREAD(ti->number) = ti; active_threads++; return ti->number; }
static int blast_client_transfer(blast_client_t* client) { int ret; socket_set_blocking(client->sock, false); blast_client_read_ack(client); ret = blast_client_send_data(client); return ret; }
static int cgw_open_listening_socket(SMSCConn *conn, PrivData *privdata) { int s; if ((s = make_server_socket(privdata->rport, (conn->our_host ? octstr_get_cstr(conn->our_host) : NULL))) == -1) { error(0, "smsc_cgw: could not create listening socket in port %d", privdata->rport); return -1; } if (socket_set_blocking(s, 0) == -1) { error(0, "smsc_cgw: couldn't make listening socket port %d non-blocking", privdata->rport); close(s); return -1; } privdata->listening_socket = s; return 0; }
static int blast_client_initialize(blast_client_t* client, network_address_t** address) { int iaddr, addrsize = 0; memset(client, 0, sizeof(blast_client_t)); client->address = address; client->state = BLAST_STATE_HANDSHAKE; client->begin_send = time_current(); array_reserve(client->pending, 1024); for (iaddr = 0, addrsize = array_size(client->address); iaddr < addrsize; ++iaddr) { socket_t* sock = udp_socket_allocate(); array_push(client->socks, sock); socket_set_blocking(sock, false); } return BLAST_RESULT_OK; }
static int conn_init_client_ssl(Connection *ret, Octstr *certkeyfile) { ret->ssl = SSL_new(global_ssl_context); /* * The current thread's error queue must be empty before * the TLS/SSL I/O operation is attempted, or SSL_get_error() * will not work reliably. */ ERR_clear_error(); if (certkeyfile != NULL) { SSL_use_certificate_file(ret->ssl, octstr_get_cstr(certkeyfile), SSL_FILETYPE_PEM); SSL_use_PrivateKey_file(ret->ssl, octstr_get_cstr(certkeyfile), SSL_FILETYPE_PEM); if (SSL_check_private_key(ret->ssl) != 1) { error(0, "conn_open_ssl: private key isn't consistent with the " "certificate from file %s (or failed reading the file)", octstr_get_cstr(certkeyfile)); return -1; } } /* SSL_set_fd can fail, so check it */ if (SSL_set_fd(ret->ssl, ret->fd) == 0) { /* SSL_set_fd failed, log error */ error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL)); return -1; } /* * make sure the socket is non-blocking while we do SSL_connect */ if (socket_set_blocking(ret->fd, 0) < 0) { return -1; } BIO_set_nbio(SSL_get_rbio(ret->ssl), 1); BIO_set_nbio(SSL_get_wbio(ret->ssl), 1); SSL_set_connect_state(ret->ssl); return 0; }
DECLARE_TEST(udp, datagram_ipv6) { network_address_t** address_local = 0; network_address_t* address = 0; network_address_t* address_server = 0; test_datagram_arg_t client_arg[4]; int server_port; int state, iaddr, asize; thread_t threads[5]; socket_t* sock_server; socket_t* sock_client[4]; if (!network_supports_ipv6()) return 0; sock_server = udp_socket_allocate(); sock_client[0] = udp_socket_allocate(); sock_client[1] = udp_socket_allocate(); sock_client[2] = udp_socket_allocate(); sock_client[3] = udp_socket_allocate(); address_local = network_address_local(); for (iaddr = 0, asize = array_size(address_local); iaddr < asize; ++iaddr) { if (network_address_family(address_local[iaddr]) == NETWORK_ADDRESSFAMILY_IPV6) { address = address_local[iaddr]; break; } } EXPECT_NE(address, 0); do { server_port = random32_range(1024, 35535); network_address_ip_set_port(address, server_port); if (socket_bind(sock_server, address)) break; } while (true); address_server = network_address_clone(address); network_address_ip_set_port(address_server, server_port); network_address_array_deallocate(address_local); state = socket_state(sock_server); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[0]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[1]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[2]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[3]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); socket_set_blocking(sock_server, true); socket_set_blocking(sock_client[0], true); socket_set_blocking(sock_client[1], true); socket_set_blocking(sock_client[2], true); socket_set_blocking(sock_client[3], true); client_arg[0].sock = sock_client[0]; client_arg[0].target = address_server; client_arg[1].sock = sock_client[1]; client_arg[1].target = address_server; client_arg[2].sock = sock_client[2]; client_arg[2].target = address_server; client_arg[3].sock = sock_client[3]; client_arg[3].target = address_server; thread_initialize(&threads[0], datagram_server_blocking_thread, sock_server, STRING_CONST("server_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[1], datagram_client_blocking_thread, &client_arg[0], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[2], datagram_client_blocking_thread, &client_arg[1], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[3], datagram_client_blocking_thread, &client_arg[2], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[4], datagram_client_blocking_thread, &client_arg[3], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&threads[0]); thread_start(&threads[1]); thread_start(&threads[2]); thread_start(&threads[3]); thread_start(&threads[4]); test_wait_for_threads_startup(threads, 5); thread_finalize(&threads[0]); thread_finalize(&threads[1]); thread_finalize(&threads[2]); thread_finalize(&threads[3]); thread_finalize(&threads[4]); socket_deallocate(sock_server); socket_deallocate(sock_client[0]); socket_deallocate(sock_client[1]); socket_deallocate(sock_client[2]); socket_deallocate(sock_client[3]); memory_deallocate(address_server); return 0; }
DECLARE_TEST(udp, stream_ipv6) { network_address_t** address_local = 0; network_address_t* address = 0; int server_port, client_port; int state, iaddr, asize; thread_t threads[2]; socket_t* sock_server; socket_t* sock_client; if (!network_supports_ipv6()) return 0; sock_server = udp_socket_allocate(); sock_client = udp_socket_allocate(); address_local = network_address_local(); for (iaddr = 0, asize = array_size(address_local); iaddr < asize; ++iaddr) { if (network_address_family(address_local[iaddr]) == NETWORK_ADDRESSFAMILY_IPV6) { address = address_local[iaddr]; break; } } EXPECT_NE(address, 0); do { server_port = random32_range(1024, 35535); network_address_ip_set_port(address, server_port); if (socket_bind(sock_server, address)) break; } while (true); do { client_port = random32_range(1024, 35535); network_address_ip_set_port(address, client_port); if (socket_bind(sock_client, address)) break; } while (true); socket_set_blocking(sock_server, false); socket_set_blocking(sock_client, false); network_address_ip_set_port(address, client_port); socket_connect(sock_server, address, 0); network_address_ip_set_port(address, server_port); socket_connect(sock_client, address, 0); network_address_array_deallocate(address_local); state = socket_state(sock_server); EXPECT_TRUE(state == SOCKETSTATE_CONNECTED); state = socket_state(sock_client); EXPECT_TRUE(state == SOCKETSTATE_CONNECTED); socket_set_blocking(sock_server, true); socket_set_blocking(sock_client, true); thread_initialize(&threads[0], stream_blocking_thread, sock_server, STRING_CONST("io_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[1], stream_blocking_thread, sock_client, STRING_CONST("io_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&threads[0]); thread_start(&threads[1]); test_wait_for_threads_startup(threads, 2); thread_finalize(&threads[0]); thread_finalize(&threads[1]); socket_deallocate(sock_server); socket_deallocate(sock_client); return 0; }