예제 #1
0
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;
}
예제 #2
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;
}