int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg, char *function, int line) { ASSERT_ON_THREAD(ststhread_); // Make sure we're waiting on the socket for the internal address int r = NrSocket::async_wait(how, cb, cb_arg, function, line); if (r) { return r; } r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %s waiting for %s", my_addr_.as_string, how == NR_ASYNC_WAIT_READ ? "read" : "write"); if (is_tcp_connection_behind_nat()) { // Bypass all port-mapping related logic return 0; } if (my_addr_.protocol == IPPROTO_TCP) { // For a TCP connection through a simulated NAT, these signals are // just passed through. MOZ_ASSERT(port_mappings_.size() == 1); return port_mappings_.front()->async_wait( how, port_mapping_tcp_passthrough_callback, this, function, line); } else if (how == NR_ASYNC_WAIT_READ) { // For UDP port mappings, we decouple the writeable callbacks for (PortMapping *port_mapping : port_mappings_) { // Be ready to receive traffic on our port mappings r = port_mapping->async_wait(how, port_mapping_readable_callback, this, function, line); if (r) { return r; } } } return 0; }
int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg, char *function, int line) { r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %s waiting for %s", internal_socket_->my_addr().as_string, how == NR_ASYNC_WAIT_READ ? "read" : "write"); int r; if (how == NR_ASYNC_WAIT_READ) { NrSocketBase::async_wait(how, cb, cb_arg, function, line); // Make sure we're waiting on the socket for the internal address r = internal_socket_->async_wait(how, socket_readable_callback, this, function, line); } else { // For write, just use the readiness of the internal socket, since we queue // everything for the port mappings. r = internal_socket_->async_wait(how, cb, cb_arg, function, line); } if (r) { r_log(LOG_GENERIC, LOG_ERR, "TestNrSocket %s failed to async_wait for " "internal socket: %d\n", internal_socket_->my_addr().as_string, r); return r; } if (is_tcp_connection_behind_nat()) { // Bypass all port-mapping related logic return 0; } if (internal_socket_->my_addr().protocol == IPPROTO_TCP) { // For a TCP connection through a simulated NAT, these signals are // just passed through. MOZ_ASSERT(port_mappings_.size() == 1); return port_mappings_.front()->async_wait( how, port_mapping_tcp_passthrough_callback, this, function, line); } if (how == NR_ASYNC_WAIT_READ) { // For UDP port mappings, we decouple the writeable callbacks for (PortMapping *port_mapping : port_mappings_) { // Be ready to receive traffic on our port mappings r = port_mapping->async_wait(how, socket_readable_callback, this, function, line); if (r) { r_log(LOG_GENERIC, LOG_ERR, "TestNrSocket %s failed to async_wait for " "port mapping: %d\n", internal_socket_->my_addr().as_string, r); return r; } } } return 0; }