/** \brief send the bt_utmsgtype_t::HANDSHAKE */ bt_err_t bt_swarm_full_utmsg_t::send_handshake() throw() { // build the payload for the bt_utmsgtype_t::HANDSHAKE pkt_t payload; payload << bt_utmsgtype_t(bt_utmsgtype_t::HANDSHAKE); payload.append(generate_handshake()); // build the bt_cmd_t to send bt_cmd_t bt_cmd = bt_cmd_t::build_utmsg_payl(payload.to_datum(datum_t::NOCOPY)); // send it thru the bt_swarm_full_t swarm_full->send_cmd( bt_cmd ); // return no error return bt_err_t::OK; }
void connection::write_handshake(const boost::system::error_code& error) { if (error) { stillborn(); return; } boost::asio::async_write(link_.socket, const_buffers_1(generate_handshake()), boost::bind(&connection::read_handshake, shared_from_this(), placeholders::error, placeholders::bytes_transferred)); }
/* Run the TCP connection */ void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata) { unix_time_update(); if (TCP_connection->status == TCP_CLIENT_DISCONNECTED) { return; } if (TCP_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { if (send_pending_data(TCP_connection) == 0) { int ret = proxy_http_read_connection_response(TCP_connection); if (ret == -1) { TCP_connection->kill_at = 0; TCP_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { generate_handshake(TCP_connection); TCP_connection->status = TCP_CLIENT_CONNECTING; } } } if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { if (send_pending_data(TCP_connection) == 0) { int ret = socks5_read_handshake_response(TCP_connection); if (ret == -1) { TCP_connection->kill_at = 0; TCP_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { proxy_socks5_generate_connection_request(TCP_connection); TCP_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; } } } if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { if (send_pending_data(TCP_connection) == 0) { int ret = proxy_socks5_read_connection_response(TCP_connection); if (ret == -1) { TCP_connection->kill_at = 0; TCP_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { generate_handshake(TCP_connection); TCP_connection->status = TCP_CLIENT_CONNECTING; } } } if (TCP_connection->status == TCP_CLIENT_CONNECTING) { if (send_pending_data(TCP_connection) == 0) { TCP_connection->status = TCP_CLIENT_UNCONFIRMED; } } if (TCP_connection->status == TCP_CLIENT_UNCONFIRMED) { uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; int len = read_TCP_packet(TCP_connection->sock, data, sizeof(data)); if (sizeof(data) == len) { if (handle_handshake(TCP_connection, data) == 0) { TCP_connection->kill_at = ~0; TCP_connection->status = TCP_CLIENT_CONFIRMED; } else { TCP_connection->kill_at = 0; TCP_connection->status = TCP_CLIENT_DISCONNECTED; } } } if (TCP_connection->status == TCP_CLIENT_CONFIRMED) { do_confirmed_TCP(TCP_connection, userdata); } if (TCP_connection->kill_at <= unix_time()) { TCP_connection->status = TCP_CLIENT_DISCONNECTED; } }
/* Create new TCP connection to ip_port/public_key */ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, TCP_Proxy_Info *proxy_info) { if (networking_at_startup() != 0) { return NULL; } if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) { return NULL; } uint8_t family = ip_port.ip.family; TCP_Proxy_Info default_proxyinfo; if (proxy_info == NULL) { default_proxyinfo.proxy_type = TCP_PROXY_NONE; proxy_info = &default_proxyinfo; } if (proxy_info->proxy_type != TCP_PROXY_NONE) { family = proxy_info->ip_port.ip.family; } Socket sock = net_socket(family, TOX_SOCK_STREAM, TOX_PROTO_TCP); if (!sock_valid(sock)) { return NULL; } if (!set_socket_nosigpipe(sock)) { kill_sock(sock); return 0; } if (!(set_socket_nonblock(sock) && connect_sock_to(sock, ip_port, proxy_info))) { kill_sock(sock); return NULL; } TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(sizeof(TCP_Client_Connection), 1); if (temp == NULL) { kill_sock(sock); return NULL; } temp->sock = sock; memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE); encrypt_precompute(temp->public_key, self_secret_key, temp->shared_key); temp->ip_port = ip_port; temp->proxy_info = *proxy_info; switch (proxy_info->proxy_type) { case TCP_PROXY_HTTP: temp->status = TCP_CLIENT_PROXY_HTTP_CONNECTING; proxy_http_generate_connection_request(temp); break; case TCP_PROXY_SOCKS5: temp->status = TCP_CLIENT_PROXY_SOCKS5_CONNECTING; proxy_socks5_generate_handshake(temp); break; case TCP_PROXY_NONE: temp->status = TCP_CLIENT_CONNECTING; if (generate_handshake(temp) == -1) { kill_sock(sock); free(temp); return NULL; } break; } temp->kill_at = unix_time() + TCP_CONNECTION_TIMEOUT; return temp; }