コード例 #1
0
// Runs on STS thread
void
UDPSocketParent::DoConnect(nsCOMPtr<nsIUDPSocket>& aSocket,
                           nsCOMPtr<nsIEventTarget>& aReturnThread,
                           const UDPAddressInfo& aAddressInfo)
{
  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
  if (NS_FAILED(ConnectInternal(aAddressInfo.addr(), aAddressInfo.port()))) {
    SendInternalError(aReturnThread, __LINE__);
    return;
  }
  CheckSTSThread();

  nsCOMPtr<nsINetAddr> localAddr;
  aSocket->GetLocalAddr(getter_AddRefs(localAddr));

  nsCString addr;
  if (NS_FAILED(localAddr->GetAddress(addr))) {
    SendInternalError(aReturnThread, __LINE__);
    return;
  }

  uint16_t port;
  if (NS_FAILED(localAddr->GetPort(&port))) {
    SendInternalError(aReturnThread, __LINE__);
    return;
  }

  UDPSOCKET_LOG(("%s: SendConnectResponse: %s:%u", __FUNCTION__, addr.get(), port));
  SendConnectResponse(aReturnThread, UDPAddressInfo(addr, port));
}
コード例 #2
0
bool
UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
                          const bool& aAddressReuse, const bool& aLoopback)
{
  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));

  if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(), aAddressReuse, aLoopback))) {
    FireInternalError(__LINE__);
    return true;
  }

  nsCOMPtr<nsINetAddr> localAddr;
  mSocket->GetLocalAddr(getter_AddRefs(localAddr));

  nsCString addr;
  if (NS_FAILED(localAddr->GetAddress(addr))) {
    FireInternalError(__LINE__);
    return true;
  }

  uint16_t port;
  if (NS_FAILED(localAddr->GetPort(&port))) {
    FireInternalError(__LINE__);
    return true;
  }

  UDPSOCKET_LOG(("%s: SendCallbackOpened: %s:%u", __FUNCTION__, addr.get(), port));
  mozilla::unused << SendCallbackOpened(UDPAddressInfo(addr, port));

  return true;
}
コード例 #3
0
NS_IMETHODIMP
UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
{
  // receiving packet from remote host, forward the message content to child process
  if (!mIPCOpen) {
    return NS_OK;
  }

  uint16_t port;
  nsCString ip;
  nsCOMPtr<nsINetAddr> fromAddr;
  aMessage->GetFromAddr(getter_AddRefs(fromAddr));
  fromAddr->GetPort(&port);
  fromAddr->GetAddress(ip);

  nsCString data;
  aMessage->GetData(data);

  const char* buffer = data.get();
  uint32_t len = data.Length();
  UDPSOCKET_LOG(("%s: %s:%u, length %u", __FUNCTION__, ip.get(), port, len));

  if (mFilter) {
    bool allowed;
    mozilla::net::NetAddr addr;
    fromAddr->GetNetAddr(&addr);
    nsresult rv = mFilter->FilterPacket(&addr,
                                        (const uint8_t*)buffer, len,
                                        nsIUDPSocketFilter::SF_INCOMING,
                                        &allowed);
    // Receiving unallowed data, drop.
    if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
      if (!allowed) {
        UDPSOCKET_LOG(("%s: not allowed", __FUNCTION__));
      }
      return NS_OK;
    }
  }

  FallibleTArray<uint8_t> fallibleArray;
  if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
    FireInternalError(__LINE__);
    return NS_ERROR_OUT_OF_MEMORY;
  }
  InfallibleTArray<uint8_t> infallibleArray;
  infallibleArray.SwapElements(fallibleArray);

  // compose callback
  mozilla::unused << SendCallbackReceivedData(UDPAddressInfo(ip, port), infallibleArray);

  return NS_OK;
}
コード例 #4
0
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;
}
コード例 #5
0
void UDPSocketParent::SendInternalError(nsIEventTarget* aThread,
                                        uint32_t aLineNo) {
  UDPSOCKET_LOG(("SendInternalError: %u", aLineNo));
  Unused << NS_WARN_IF(NS_FAILED(aThread->Dispatch(
      WrapRunnable(RefPtr<UDPSocketParent>(this),
                   &UDPSocketParent::FireInternalError, aLineNo),
      NS_DISPATCH_NORMAL)));
}
コード例 #6
0
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;
}
コード例 #7
0
ファイル: nsUDPSocket.cpp プロジェクト: brendandahl/positron
void
nsUDPSocket::OnMsgAttach()
{
  UDPSOCKET_LOG(("nsUDPSocket::OnMsgAttach [this=%p]\n", this));

  if (NS_FAILED(mCondition))
    return;

  mCondition = TryAttach();

  // if we hit an error while trying to attach then bail...
  if (NS_FAILED(mCondition))
  {
    NS_ASSERTION(!mAttached, "should not be attached already");
    OnSocketDetached(mFD);
  }
}
コード例 #8
0
ファイル: nsUDPSocket.cpp プロジェクト: brendandahl/positron
void
nsUDPSocket::OnMsgClose()
{
  UDPSOCKET_LOG(("nsUDPSocket::OnMsgClose [this=%p]\n", this));

  if (NS_FAILED(mCondition))
    return;

  // tear down socket.  this signals the STS to detach our socket handler.
  mCondition = NS_BINDING_ABORTED;

  // if we are attached, then socket transport service will call our
  // OnSocketDetached method automatically. Otherwise, we have to call it
  // (and thus close the socket) manually.
  if (!mAttached)
    OnSocketDetached(mFD);
}
コード例 #9
0
ファイル: UDPSocket.cpp プロジェクト: SJasoria/gecko-dev
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;
}
コード例 #10
0
ファイル: UDPSocket.cpp プロジェクト: SJasoria/gecko-dev
bool
UDPSocket::Send(const StringOrBlobOrArrayBufferOrArrayBufferView& aData,
                const Optional<nsAString>& aRemoteAddress,
                const Optional<Nullable<uint16_t>>& aRemotePort,
                ErrorResult& aRv)
{
  if (mReadyState != SocketReadyState::Open) {
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
    return false;
  }

  MOZ_ASSERT(mSocket || mSocketChild);

  // If the remote address and port were not specified in the constructor or as arguments,
  // throw InvalidAccessError.
  nsCString remoteAddress;
  if (aRemoteAddress.WasPassed()) {
    remoteAddress = NS_ConvertUTF16toUTF8(aRemoteAddress.Value());
    UDPSOCKET_LOG(("%s: Send to %s", __FUNCTION__, remoteAddress.get()));
  } else if (!mRemoteAddress.IsVoid()) {
    remoteAddress = mRemoteAddress;
    UDPSOCKET_LOG(("%s: Send to %s", __FUNCTION__, remoteAddress.get()));
  } else {
    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
    return false;
  }

  uint16_t remotePort;
  if (aRemotePort.WasPassed() && !aRemotePort.Value().IsNull()) {
    remotePort = aRemotePort.Value().Value();
  } else if (!mRemotePort.IsNull()) {
    remotePort = mRemotePort.Value();
  } else {
    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
    return false;
  }

  nsCOMPtr<nsIInputStream> stream;
  if (aData.IsBlob()) {
    Blob& blob = aData.GetAsBlob();

    blob.GetInternalStream(getter_AddRefs(stream), aRv);
    if (NS_WARN_IF(aRv.Failed())) {
      return false;
    }
  } else {
    nsresult rv;
    nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      aRv.Throw(rv);
      return false;
    }

    if (aData.IsString()) {
      NS_ConvertUTF16toUTF8 data(aData.GetAsString());
      aRv = strStream->SetData(data.BeginReading(), data.Length());
    } else if (aData.IsArrayBuffer()) {
      const ArrayBuffer& data = aData.GetAsArrayBuffer();
      data.ComputeLengthAndData();
      aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()), data.Length());
    } else {
      const ArrayBufferView& data = aData.GetAsArrayBufferView();
      data.ComputeLengthAndData();
      aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()), data.Length());
    }

    if (NS_WARN_IF(aRv.Failed())) {
      return false;
    }

    stream = strStream;
  }

  if (mSocket) {
    aRv = mSocket->SendBinaryStream(remoteAddress, remotePort, stream);
  } else if (mSocketChild) {
    aRv = mSocketChild->SendBinaryStream(remoteAddress, remotePort, stream);
  }

  if (NS_WARN_IF(aRv.Failed())) {
    return false;
  }

  return true;
}
コード例 #11
0
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;
}