int NrSocket::recvfrom(void * buf, size_t maxlen, size_t *len, int flags, nr_transport_addr *from) { ASSERT_ON_THREAD(ststhread_); int r,_status; PRNetAddr nfrom; int32_t status; status = PR_RecvFrom(fd_, buf, maxlen, flags, &nfrom, PR_INTERVAL_NO_WAIT); if (status <= 0) { if (PR_GetError() == PR_WOULD_BLOCK_ERROR) ABORT(R_WOULDBLOCK); r_log(LOG_GENERIC, LOG_INFO, "Error in recvfrom"); ABORT(R_IO_ERROR); } *len=status; if((r=nr_praddr_to_transport_addr(&nfrom,from,my_addr_.protocol,0))) ABORT(r); //r_log(LOG_GENERIC,LOG_DEBUG,"Read %d bytes from %s",*len,addr->as_string); _status=0; abort: return(_status); }
nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server) const { int r; memset(server, 0, sizeof(nr_ice_stun_server)); if (transport_ == kNrIceTransportUdp) { server->transport = IPPROTO_UDP; } else if (transport_ == kNrIceTransportTcp) { server->transport = IPPROTO_TCP; } else { MOZ_ASSERT(false); return NS_ERROR_FAILURE; } if (has_addr_) { r = nr_praddr_to_transport_addr(&addr_, &server->u.addr, server->transport, 0); if (r) { return NS_ERROR_FAILURE; } server->type=NR_ICE_STUN_SERVER_TYPE_ADDR; } else { MOZ_ASSERT(sizeof(server->u.dnsname.host) > host_.size()); PL_strncpyz(server->u.dnsname.host, host_.c_str(), sizeof(server->u.dnsname.host)); server->u.dnsname.port = port_; server->type=NR_ICE_STUN_SERVER_TYPE_DNSNAME; } return NS_OK; }
nsresult NrIceCtx::SetStunServers(const std::vector<NrIceStunServer>& stun_servers) { if (stun_servers.empty()) return NS_OK; ScopedDeleteArray<nr_ice_stun_server> servers( new nr_ice_stun_server[stun_servers.size()]); int r; for (size_t i=0; i < stun_servers.size(); ++i) { r = nr_praddr_to_transport_addr(&stun_servers[i].addr(), &servers[i].addr, 0); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't set STUN server for '" << name_ << "'"); return NS_ERROR_FAILURE; } } r = nr_ice_ctx_set_stun_servers(ctx_, servers, stun_servers.size()); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't set STUN server for '" << name_ << "'"); return NS_ERROR_FAILURE; } return NS_OK; }
// callback while UDP socket is opened or closed NS_IMETHODIMP NrSocketIpc::CallListenerVoid(const nsACString &type) { ASSERT_ON_THREAD(main_thread_); if (type.EqualsLiteral("onopen")) { ReentrantMonitorAutoEnter mon(monitor_); uint16_t port; if (NS_FAILED(socket_child_->GetLocalPort(&port))) { err_ = true; MOZ_ASSERT(false, "Failed to get local port"); return NS_OK; } nsAutoCString address; if(NS_FAILED(socket_child_->GetLocalAddress(address))) { err_ = true; MOZ_ASSERT(false, "Failed to get local address"); return NS_OK; } PRNetAddr praddr; if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) { err_ = true; MOZ_ASSERT(false, "Failed to set port in PRNetAddr"); return NS_OK; } if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) { err_ = true; MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr"); return NS_OK; } nr_transport_addr expected_addr; if(nr_transport_addr_copy(&expected_addr, &my_addr_)) { err_ = true; MOZ_ASSERT(false, "Failed to copy my_addr_"); } if (nr_praddr_to_transport_addr(&praddr, &my_addr_, 1)) { err_ = true; MOZ_ASSERT(false, "Failed to copy local host to my_addr_"); } if (nr_transport_addr_cmp(&expected_addr, &my_addr_, NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) { err_ = true; MOZ_ASSERT(false, "Address of opened socket is not expected"); } mon.NotifyAll(); } else if (type.EqualsLiteral("onclose")) { // Already handled in UpdateReadyState, nothing to do here } else { MOZ_ASSERT(false, "Received unexpected event"); } return NS_OK; }
// callback while UDP socket is opened NS_IMETHODIMP NrSocketIpc::CallListenerOpened() { ASSERT_ON_THREAD(main_thread_); ReentrantMonitorAutoEnter mon(monitor_); uint16_t port; if (NS_FAILED(socket_child_->GetLocalPort(&port))) { err_ = true; MOZ_ASSERT(false, "Failed to get local port"); return NS_OK; } nsAutoCString address; if(NS_FAILED(socket_child_->GetLocalAddress(address))) { err_ = true; MOZ_ASSERT(false, "Failed to get local address"); return NS_OK; } PRNetAddr praddr; if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) { err_ = true; MOZ_ASSERT(false, "Failed to set port in PRNetAddr"); return NS_OK; } if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) { err_ = true; MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr"); return NS_OK; } nr_transport_addr expected_addr; if(nr_transport_addr_copy(&expected_addr, &my_addr_)) { err_ = true; MOZ_ASSERT(false, "Failed to copy my_addr_"); } if (nr_praddr_to_transport_addr(&praddr, &my_addr_, IPPROTO_UDP, 1)) { err_ = true; MOZ_ASSERT(false, "Failed to copy local host to my_addr_"); } if (nr_transport_addr_cmp(&expected_addr, &my_addr_, NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) { err_ = true; MOZ_ASSERT(false, "Address of opened socket is not expected"); } mon.NotifyAll(); return NS_OK; }
int NrSocketIpc::recvfrom(void *buf, size_t maxlen, size_t *len, int flags, nr_transport_addr *from) { ASSERT_ON_THREAD(sts_thread_); ReentrantMonitorAutoEnter mon(monitor_); int r, _status; uint32_t consumed_len; *len = 0; if (state_ != NR_CONNECTED) { ABORT(R_INTERNAL); } if (received_msgs_.empty()) { ABORT(R_WOULDBLOCK); } { RefPtr<nr_udp_message> msg(received_msgs_.front()); received_msgs_.pop(); if ((r=nr_praddr_to_transport_addr(&msg->from, from, IPPROTO_UDP, 0))) { err_ = true; MOZ_ASSERT(false, "Get bogus address for received UDP packet"); ABORT(r); } consumed_len = std::min(maxlen, msg->data->len()); if (consumed_len < msg->data->len()) { r_log(LOG_GENERIC, LOG_DEBUG, "Partial received UDP packet will be discard"); } memcpy(buf, msg->data->data(), consumed_len); *len = consumed_len; } _status = 0; abort: return(_status); }
nsresult NrIceStunServer::ToNicerStruct(nr_ice_stun_server *server) const { int r; if (has_addr_) { r = nr_praddr_to_transport_addr(&addr_, &server->u.addr, 0); if (r) { return NS_ERROR_FAILURE; } server->type=NR_ICE_STUN_SERVER_TYPE_ADDR; } else { MOZ_ASSERT(sizeof(server->u.dnsname.host) > host_.size()); PL_strncpyz(server->u.dnsname.host, host_.c_str(), sizeof(server->u.dnsname.host)); server->u.dnsname.port = port_; server->type=NR_ICE_STUN_SERVER_TYPE_DNSNAME; } return NS_OK; }
int NrSocket::recvfrom(void * buf, size_t maxlen, size_t *len, int flags, nr_transport_addr *from) { int r,_status; PRNetAddr nfrom; int32_t status; status = PR_RecvFrom(fd_, buf, maxlen, flags, &nfrom, PR_INTERVAL_NO_WAIT); if (status <= 0) { r_log_e(LOG_GENERIC,LOG_ERR,"Error in recvfrom"); ABORT(R_IO_ERROR); } *len=status; if((r=nr_praddr_to_transport_addr(&nfrom,from,0))) ABORT(r); //r_log(LOG_GENERIC,LOG_DEBUG,"Read %d bytes from %s",*len,addr->as_string); _status=0; abort: return(_status); }
void NrIceResolverFake::resolve_cb(NR_SOCKET s, int how, void *cb_arg) { MOZ_ASSERT(cb_arg); PendingResolution *pending = static_cast<PendingResolution *>(cb_arg); const PRNetAddr *addr=pending->resolver_->Resolve(pending->hostname_); if (addr) { nr_transport_addr transport_addr; int r = nr_praddr_to_transport_addr(addr, &transport_addr, 0); MOZ_ASSERT(!r); if (r) goto abort; r=nr_transport_addr_set_port(&transport_addr, pending->port_); MOZ_ASSERT(!r); if (r) goto abort; /* Fill in the address string */ r=nr_transport_addr_fmt_addr_string(&transport_addr); MOZ_ASSERT(!r); if (r) goto abort; pending->cb_(pending->cb_arg_, &transport_addr); delete pending; return; } abort: // Resolution failed. pending->cb_(pending->cb_arg_, nullptr); delete pending; }
// nr_socket APIs (as member functions) int NrSocket::create(nr_transport_addr *addr) { int r,_status; PRStatus status; PRNetAddr naddr; nsresult rv; nsCOMPtr<nsISocketTransportService> stservice = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) { ABORT(R_INTERNAL); } if((r=nr_transport_addr_to_praddr(addr, &naddr))) ABORT(r); switch (addr->protocol) { case IPPROTO_UDP: if (!(fd_ = PR_NewUDPSocket())) { r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create socket"); ABORT(R_INTERNAL); } break; case IPPROTO_TCP: if (!(fd_ = PR_NewTCPSocket())) { r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create socket"); ABORT(R_INTERNAL); } break; default: ABORT(R_INTERNAL); } status = PR_Bind(fd_, &naddr); if (status != PR_SUCCESS) { r_log(LOG_GENERIC,LOG_CRIT,"Couldn't bind socket to address %s", addr->as_string); ABORT(R_INTERNAL); } r_log(LOG_GENERIC,LOG_DEBUG,"Creating socket %p with addr %s", fd_, addr->as_string); nr_transport_addr_copy(&my_addr_,addr); /* If we have a wildcard port, patch up the addr */ if(nr_transport_addr_is_wildcard(addr)){ status = PR_GetSockName(fd_, &naddr); if (status != PR_SUCCESS){ r_log(LOG_GENERIC, LOG_CRIT, "Couldn't get sock name for socket"); ABORT(R_INTERNAL); } if((r=nr_praddr_to_transport_addr(&naddr,&my_addr_,addr->protocol,1))) ABORT(r); } // Set nonblocking PRSocketOptionData option; option.option = PR_SockOpt_Nonblocking; option.value.non_blocking = PR_TRUE; status = PR_SetSocketOption(fd_, &option); if (status != PR_SUCCESS) { r_log(LOG_GENERIC, LOG_CRIT, "Couldn't make socket nonblocking"); ABORT(R_INTERNAL); } // Remember our thread. ststhread_ = do_QueryInterface(stservice, &rv); if (!NS_SUCCEEDED(rv)) ABORT(R_INTERNAL); // Finally, register with the STS rv = stservice->AttachSocket(fd_, this); if (!NS_SUCCEEDED(rv)) { ABORT(R_INTERNAL); } _status = 0; abort: return(_status); }