예제 #1
0
void TestNrSocket::fire_readable_callback() {
  MOZ_ASSERT(poll_flags() & PR_POLL_READ);
  // Stop listening on all mapped sockets; we will start listening again
  // if the app starts listening to us again.
  cancel_port_mapping_async_wait(NR_ASYNC_WAIT_READ);
  r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %s ready for read",
        my_addr_.as_string);
  fire_callback(NR_ASYNC_WAIT_READ);
}
예제 #2
0
int NrSocket::cancel(int how) {
  int r = NrSocketBase::cancel(how);

  if (!r) {
    mPollFlags = poll_flags();
  }

  return r;
}
예제 #3
0
// async_event APIs
int NrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg,
                         char *function, int line) {
  int r = NrSocketBase::async_wait(how, cb, cb_arg, function, line);

  if (!r) {
    mPollFlags = poll_flags();
  }

  return r;
}
예제 #4
0
int TestNrSocket::sendto(const void *msg, size_t len,
                         int flags, nr_transport_addr *to) {
  MOZ_ASSERT(my_addr_.protocol != IPPROTO_TCP);
  ASSERT_ON_THREAD(ststhread_);

  if (!nat_->enabled_ || nat_->is_an_internal_tuple(*to)) {
    return NrSocket::sendto(msg, len, flags, to);
  }

  destroy_stale_port_mappings();

  if (to->protocol == IPPROTO_UDP && nat_->block_udp_) {
    // Silently eat the packet
    return 0;
  }

  // Choose our port mapping based on our most selective criteria
  PortMapping *port_mapping = get_port_mapping(*to,
                                               std::max(nat_->filtering_type_,
                                                        nat_->mapping_type_));

  if (!port_mapping) {
    // See if we have already made the external socket we need to use.
    PortMapping *similar_port_mapping =
      get_port_mapping(*to, nat_->mapping_type_);
    nsRefPtr<NrSocket> external_socket;

    if (similar_port_mapping) {
      external_socket = similar_port_mapping->external_socket_;
    } else {
      external_socket = create_external_socket(*to);
      if (!external_socket) {
        MOZ_ASSERT(false);
        return R_INTERNAL;
      }
    }

    port_mapping = create_port_mapping(*to, external_socket);
    port_mappings_.push_back(port_mapping);

    if (poll_flags() & PR_POLL_READ) {
      // Make sure the new port mapping is ready to receive traffic if the
      // TestNrSocket is already waiting.
      port_mapping->async_wait(NR_ASYNC_WAIT_READ,
                              port_mapping_readable_callback,
                              this,
                              (char*)__FUNCTION__,
                              __LINE__);
    }
  }

  // We probably don't want to propagate the flags, since this is a simulated
  // external IP address.
  return port_mapping->sendto(msg, len, *to);
}
예제 #5
0
void TestNrSocket::on_port_mapping_readable(NrSocket *external_socket) {
  if (!readable_socket_) {
    readable_socket_ = external_socket;
  }

  // None of our port mappings should be waiting for readable callbacks
  // if nobody is waiting for readable callbacks from us.
  MOZ_ASSERT(poll_flags() & PR_POLL_READ);

  fire_readable_callback();
}
예제 #6
0
void NrSocketIpc::recv_callback_s(RefPtr<nr_udp_message> msg) {
  ASSERT_ON_THREAD(sts_thread_);

  {
    ReentrantMonitorAutoEnter mon(monitor_);
    if (state_ != NR_CONNECTED) {
      return;
    }
  }

  //enqueue received message
  received_msgs_.push(msg);

  if ((poll_flags() & PR_POLL_READ)) {
    fire_callback(NR_ASYNC_WAIT_READ);
  }
}
예제 #7
0
int TestNrSocket::connect(nr_transport_addr *addr) {

  if (connect_invoked_ || !port_mappings_.empty()) {
    MOZ_CRASH("TestNrSocket::connect() called more than once!");
    return R_INTERNAL;
  }

  if (!nat_->enabled_
      || addr->protocol==IPPROTO_UDP  // Horrible hack to allow default address
                                      // discovery to work. Only works because
                                      // we don't normally connect on UDP.
      || nat_->is_an_internal_tuple(*addr)) {
    // This will set connect_invoked_
    return internal_socket_->connect(addr);
  }

  RefPtr<NrSocketBase> external_socket(create_external_socket(*addr));
  if (!external_socket) {
    return R_INTERNAL;
  }

  PortMapping *port_mapping = create_port_mapping(*addr, external_socket);
  port_mappings_.push_back(port_mapping);
  int r = port_mapping->external_socket_->connect(addr);
  if (r && r != R_WOULDBLOCK) {
    return r;
  }

  port_mapping->last_used_ = PR_IntervalNow();

  if (poll_flags() & PR_POLL_READ) {
    port_mapping->async_wait(NR_ASYNC_WAIT_READ,
                             port_mapping_tcp_passthrough_callback,
                             this,
                             (char*)__FUNCTION__,
                             __LINE__);
  }

  return r;
}
예제 #8
0
void TestNrSocket::fire_readable_callback() {
  MOZ_ASSERT(poll_flags() & PR_POLL_READ);
  r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %s ready for read",
        internal_socket_->my_addr().as_string);
  fire_callback(NR_ASYNC_WAIT_READ);
}
예제 #9
0
int TestNrSocket::sendto(const void *msg, size_t len,
                         int flags, nr_transport_addr *to) {
  MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP);

  UCHAR *buf = static_cast<UCHAR*>(const_cast<void*>(msg));
  if (nat_->block_stun_ &&
      nr_is_stun_message(buf, len)) {
    return 0;
  }

  /* TODO: improve the functionality of this in bug 1253657 */
  if (!nat_->enabled_ || nat_->is_an_internal_tuple(*to)) {
    if (nat_->delay_stun_resp_ms_ &&
        nr_is_stun_response_message(buf, len)) {
      NR_ASYNC_TIMER_SET(nat_->delay_stun_resp_ms_,
                         process_delayed_cb,
                         new DeferredPacket(this, msg, len, flags, to,
                                            internal_socket_),
                         &timer_handle_);
      return 0;
    }
    return internal_socket_->sendto(msg, len, flags, to);
  }

  destroy_stale_port_mappings();

  if (to->protocol == IPPROTO_UDP && nat_->block_udp_) {
    // Silently eat the packet
    return 0;
  }

  // Choose our port mapping based on our most selective criteria
  PortMapping *port_mapping = get_port_mapping(*to,
                                               std::max(nat_->filtering_type_,
                                                        nat_->mapping_type_));

  if (!port_mapping) {
    // See if we have already made the external socket we need to use.
    PortMapping *similar_port_mapping =
      get_port_mapping(*to, nat_->mapping_type_);
    RefPtr<NrSocketBase> external_socket;

    if (similar_port_mapping) {
      external_socket = similar_port_mapping->external_socket_;
    } else {
      external_socket = create_external_socket(*to);
      if (!external_socket) {
        MOZ_ASSERT(false);
        return R_INTERNAL;
      }
    }

    port_mapping = create_port_mapping(*to, external_socket);
    port_mappings_.push_back(port_mapping);

    if (poll_flags() & PR_POLL_READ) {
      // Make sure the new port mapping is ready to receive traffic if the
      // TestNrSocket is already waiting.
      port_mapping->async_wait(NR_ASYNC_WAIT_READ,
                              socket_readable_callback,
                              this,
                              (char*)__FUNCTION__,
                              __LINE__);
    }
  }

  // We probably don't want to propagate the flags, since this is a simulated
  // external IP address.
  return port_mapping->sendto(msg, len, *to);
}