nsresult UDPSocketParent::ConnectInternal(const nsCString& aHost,
                                          const uint16_t& aPort) {
  nsresult rv;

  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));

  if (!mSocket) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  PRNetAddr prAddr;
  memset(&prAddr, 0, sizeof(prAddr));
  PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
  PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
  if (status != PR_SUCCESS) {
    return NS_ERROR_FAILURE;
  }

  mozilla::net::NetAddr addr;
  PRNetAddrToNetAddr(&prAddr, &addr);

  rv = mSocket->Connect(&addr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  return NS_OK;
}
bool
UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
{
  nsresult rv;
  NS_ASSERTION(mFilter, "No packet filter");

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      FireInternalError(this, __LINE__);
      return true;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr);
  }

  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  mSocket = sock;

  net::NetAddr localAddr;
  mSocket->GetAddress(&localAddr);

  uint16_t port;
  nsCString addr;
  rv = ConvertNetAddrToString(localAddr, &addr, &port);

  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  // register listener
  mSocket->AsyncListen(this);
  mozilla::unused <<
      PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"),
                                     UDPAddressInfo(addr, port),
                                     NS_LITERAL_CSTRING("connected"));

  return true;
}
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
                              const bool& aAddressReuse, const bool& aLoopback)
{
  nsresult rv;

  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
                    /* optional_argc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      return NS_ERROR_FAILURE;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
                               /* optional_argc = */ 1);
  }

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  rv = sock->SetMulticastLoopback(aLoopback);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  // register listener
  rv = sock->AsyncListen(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  mSocket = sock;

  return NS_OK;
}
bool
nsHttpConnectionInfo::HostIsLocalIPLiteral() const
{
    PRNetAddr prAddr;
    // If the host/proxy host is not an IP address literal, return false.
    if (ProxyHost()) {
        if (PR_StringToNetAddr(ProxyHost(), &prAddr) != PR_SUCCESS) {
          return false;
        }
    } else if (PR_StringToNetAddr(Origin(), &prAddr) != PR_SUCCESS) {
        return false;
    }
    NetAddr netAddr;
    PRNetAddrToNetAddr(&prAddr, &netAddr);
    return IsIPAddrLocal(&netAddr);
}
void
nsServerSocket::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
{
  NS_ASSERTION(NS_SUCCEEDED(mCondition), "oops");
  NS_ASSERTION(mFD == fd, "wrong file descriptor");
  NS_ASSERTION(outFlags != -1, "unexpected timeout condition reached");

  if (outFlags & (PR_POLL_ERR | PR_POLL_HUP | PR_POLL_NVAL))
  {
    NS_WARNING("error polling on listening socket");
    mCondition = NS_ERROR_UNEXPECTED;
    return;
  }

  PRFileDesc *clientFD;
  PRNetAddr prClientAddr;
  NetAddr clientAddr;

  // NSPR doesn't tell us the peer address's length (as provided by the
  // 'accept' system call), so we can't distinguish between named,
  // unnamed, and abstract peer addresses. Clear prClientAddr first, so
  // that the path will at least be reliably empty for unnamed and
  // abstract addresses, and not garbage when the peer is unnamed.
  memset(&prClientAddr, 0, sizeof(prClientAddr));

  clientFD = PR_Accept(mFD, &prClientAddr, PR_INTERVAL_NO_WAIT);
  PRNetAddrToNetAddr(&prClientAddr, &clientAddr);
  if (!clientFD) {
    NS_WARNING("PR_Accept failed");
    mCondition = NS_ERROR_UNEXPECTED;
    return;
  }

  // Accept succeeded, create socket transport and notify consumer
  CreateClientTransport(clientFD, clientAddr);
}
bool
TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
                              const uint16_t& aRemotePort,
                              const nsCString& aLocalAddr,
                              const uint16_t& aLocalPort,
                              const bool&     aUseSSL,
                              const bool&     aUseArrayBuffers,
                              const nsCString& aFilter)
{
  if (net::UsingNeckoIPCSecurity() &&
      !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) {
    FireInteralError(this, __LINE__);
    return true;
  }

  nsresult rv;
  nsCOMPtr<nsISocketTransportService> sts =
    do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  nsCOMPtr<nsISocketTransport> socketTransport;
  rv = sts->CreateTransport(nullptr, 0,
                            aRemoteHost, aRemotePort,
                            nullptr, getter_AddRefs(socketTransport));
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  PRNetAddr prAddr;
  if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
    FireInteralError(this, __LINE__);
    return true;
  }
  if (PR_SUCCESS != PR_StringToNetAddr(aLocalAddr.BeginReading(), &prAddr)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  mozilla::net::NetAddr addr;
  PRNetAddrToNetAddr(&prAddr, &addr);
  rv = socketTransport->Bind(&addr);
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  if (!aFilter.IsEmpty()) {
    nsAutoCString contractId(NS_NETWORK_TCP_SOCKET_FILTER_HANDLER_PREFIX);
    contractId.Append(aFilter);
    nsCOMPtr<nsISocketFilterHandler> filterHandler =
      do_GetService(contractId.get());
    if (!filterHandler) {
      NS_ERROR("Content doesn't have a valid filter");
      FireInteralError(this, __LINE__);
      return true;
    }
    rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
    if (NS_FAILED(rv)) {
      NS_ERROR("Cannot create filter that content specified");
      FireInteralError(this, __LINE__);
      return true;
    }
  }

  // Obtain App ID
  uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
  bool     inIsolatedMozBrowser = false;
  const PContentParent *content = Manager()->Manager();
  if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) {
    // appId's are for B2G only currently, where managees.Count() == 1
    // This is not guaranteed currently in Desktop, so skip this there.
    TabParent *tab = TabParent::GetFrom(browser);
    appId = tab->OwnAppId();
    inIsolatedMozBrowser = tab->IsIsolatedMozBrowserElement();
  }

  mSocket = new TCPSocket(nullptr, NS_ConvertUTF8toUTF16(aRemoteHost), aRemotePort, aUseSSL, aUseArrayBuffers);
  mSocket->SetAppIdAndBrowser(appId, inIsolatedMozBrowser);
  mSocket->SetSocketBridgeParent(this);
  rv = mSocket->InitWithUnconnectedTransport(socketTransport);
  NS_ENSURE_SUCCESS(rv, true);
  return true;
}
Exemple #7
0
nsresult
UDPSocket::InitLocal(const nsAString& aLocalAddress,
                     const uint16_t& aLocalPort)
{
  nsresult rv;

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner(), &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsCOMPtr<nsIPrincipal> principal = global->PrincipalOrNull();
  if (!principal) {
    return NS_ERROR_FAILURE;
  }

  if (aLocalAddress.IsEmpty()) {
    rv = sock->Init(aLocalPort, /* loopback = */ false, principal,
                    mAddressReuse, /* optionalArgc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr);
    PR_StringToNetAddr(NS_ConvertUTF16toUTF8(aLocalAddress).BeginReading(), &prAddr);
    UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, NS_ConvertUTF16toUTF8(aLocalAddress).get(), aLocalPort));

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, principal, mAddressReuse,
                               /* optionalArgc = */ 1);
  }
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = sock->SetMulticastLoopback(mLoopback);
  if (NS_FAILED(rv)) {
    return rv;
  }

  mSocket = sock;

  // Get real local address and local port
  nsCOMPtr<nsINetAddr> localAddr;
  rv = mSocket->GetLocalAddr(getter_AddRefs(localAddr));
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsCString localAddress;
  rv = localAddr->GetAddress(localAddress);
  if (NS_FAILED(rv)) {
    return rv;
  }
  mLocalAddress = NS_ConvertUTF8toUTF16(localAddress);

  uint16_t localPort;
  rv = localAddr->GetPort(&localPort);
  if (NS_FAILED(rv)) {
    return rv;
  }
  mLocalPort.SetValue(localPort);

  mListenerProxy = new ListenerProxy(this);

  rv = mSocket->AsyncListen(mListenerProxy);
  if (NS_FAILED(rv)) {
    return rv;
  }

  mReadyState = SocketReadyState::Open;
  rv = DoPendingMcastCommand();
  if (NS_FAILED(rv)) {
    return rv;
  }

  mOpened->MaybeResolve(JS::UndefinedHandleValue);

  return NS_OK;
}
Exemple #8
0
NetAddrElement::NetAddrElement(const PRNetAddr *prNetAddr)
{
  PRNetAddrToNetAddr(prNetAddr, &mAddress);
}
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
                              const bool& aAddressReuse, const bool& aLoopback,
                              const uint32_t& recvBufferSize,
                              const uint32_t& sendBufferSize)
{
  nsresult rv;

  UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %lu, sendBufferSize: %lu",
                __FUNCTION__, this, nsCString(aHost).get(), aPort,
                aAddressReuse, aLoopback, recvBufferSize, sendBufferSize));

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
                    /* optional_argc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      return NS_ERROR_FAILURE;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
                               /* optional_argc = */ 1);
  }

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  nsCOMPtr<nsINetAddr> laddr;
  rv = sock->GetLocalAddr(getter_AddRefs(laddr));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  uint16_t family;
  rv = laddr->GetFamily(&family);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  if (family == nsINetAddr::FAMILY_INET) {
    rv = sock->SetMulticastLoopback(aLoopback);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }
  // TODO: once bug 1252759 is fixed query buffer first and only increase
  if (recvBufferSize != 0) {
    rv = sock->SetRecvBufferSize(recvBufferSize);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize));
    }
  }
  if (sendBufferSize != 0) {
    rv = sock->SetSendBufferSize(sendBufferSize);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set send buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, sendBufferSize));
    }
  }

  // register listener
  rv = sock->AsyncListen(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  mSocket = sock;

  return NS_OK;
}