123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "UDPSocket.h"
- #include "mozilla/AsyncEventDispatcher.h"
- #include "mozilla/dom/File.h"
- #include "mozilla/dom/ErrorEvent.h"
- #include "mozilla/dom/UDPMessageEvent.h"
- #include "mozilla/dom/UDPSocketBinding.h"
- #include "mozilla/dom/UnionTypes.h"
- #include "mozilla/net/DNS.h"
- #include "nsComponentManagerUtils.h"
- #include "nsContentUtils.h"
- #include "nsINetAddr.h"
- #include "nsStringStream.h"
- using namespace mozilla::net;
- namespace mozilla {
- namespace dom {
- NS_IMPL_ISUPPORTS(UDPSocket::ListenerProxy,
- nsIUDPSocketListener,
- nsIUDPSocketInternal)
- NS_IMPL_CYCLE_COLLECTION_CLASS(UDPSocket)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(UDPSocket, DOMEventTargetHelper)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpened)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mClosed)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(UDPSocket, DOMEventTargetHelper)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpened)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mClosed)
- tmp->CloseWithReason(NS_OK);
- NS_IMPL_CYCLE_COLLECTION_UNLINK_END
- NS_IMPL_ADDREF_INHERITED(UDPSocket, DOMEventTargetHelper)
- NS_IMPL_RELEASE_INHERITED(UDPSocket, DOMEventTargetHelper)
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(UDPSocket)
- NS_INTERFACE_MAP_ENTRY(nsIUDPSocketListener)
- NS_INTERFACE_MAP_ENTRY(nsIUDPSocketInternal)
- NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
- /* static */ already_AddRefed<UDPSocket>
- UDPSocket::Constructor(const GlobalObject& aGlobal,
- const UDPOptions& aOptions,
- ErrorResult& aRv)
- {
- nsCOMPtr<nsPIDOMWindowInner> ownerWindow = do_QueryInterface(aGlobal.GetAsSupports());
- if (!ownerWindow) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
- bool addressReuse = aOptions.mAddressReuse;
- bool loopback = aOptions.mLoopback;
- nsCString remoteAddress;
- if (aOptions.mRemoteAddress.WasPassed()) {
- remoteAddress = NS_ConvertUTF16toUTF8(aOptions.mRemoteAddress.Value());
- } else {
- remoteAddress.SetIsVoid(true);
- }
- Nullable<uint16_t> remotePort;
- if (aOptions.mRemotePort.WasPassed()) {
- remotePort.SetValue(aOptions.mRemotePort.Value());
- if (remotePort.Value() == 0) {
- aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
- return nullptr;
- }
- }
- nsString localAddress;
- if (aOptions.mLocalAddress.WasPassed()) {
- localAddress = aOptions.mLocalAddress.Value();
- // check if localAddress is a valid IPv4/6 address
- NS_ConvertUTF16toUTF8 address(localAddress);
- PRNetAddr prAddr;
- PRStatus status = PR_StringToNetAddr(address.BeginReading(), &prAddr);
- if (status != PR_SUCCESS) {
- aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
- return nullptr;
- }
- } else {
- SetDOMStringToNull(localAddress);
- }
- Nullable<uint16_t> localPort;
- if (aOptions.mLocalPort.WasPassed()) {
- localPort.SetValue(aOptions.mLocalPort.Value());
- if (localPort.Value() == 0) {
- aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
- return nullptr;
- }
- }
- RefPtr<UDPSocket> socket = new UDPSocket(ownerWindow, remoteAddress, remotePort);
- aRv = socket->Init(localAddress, localPort, addressReuse, loopback);
- if (NS_WARN_IF(aRv.Failed())) {
- return nullptr;
- }
- return socket.forget();
- }
- UDPSocket::UDPSocket(nsPIDOMWindowInner* aOwner,
- const nsCString& aRemoteAddress,
- const Nullable<uint16_t>& aRemotePort)
- : DOMEventTargetHelper(aOwner)
- , mRemoteAddress(aRemoteAddress)
- , mRemotePort(aRemotePort)
- , mAddressReuse(false)
- , mLoopback(false)
- , mReadyState(SocketReadyState::Opening)
- {
- MOZ_ASSERT(aOwner);
- MOZ_ASSERT(aOwner->IsInnerWindow());
- nsIDocument* aDoc = aOwner->GetExtantDoc();
- if (aDoc) {
- aDoc->DisallowBFCaching();
- }
- }
- UDPSocket::~UDPSocket()
- {
- CloseWithReason(NS_OK);
- }
- JSObject*
- UDPSocket::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
- {
- return UDPSocketBinding::Wrap(aCx, this, aGivenProto);
- }
- void
- UDPSocket::DisconnectFromOwner()
- {
- DOMEventTargetHelper::DisconnectFromOwner();
- CloseWithReason(NS_OK);
- }
- already_AddRefed<Promise>
- UDPSocket::Close()
- {
- MOZ_ASSERT(mClosed);
- RefPtr<Promise> promise = mClosed;
- if (mReadyState == SocketReadyState::Closed) {
- return promise.forget();
- }
- CloseWithReason(NS_OK);
- return promise.forget();
- }
- void
- UDPSocket::CloseWithReason(nsresult aReason)
- {
- if (mReadyState == SocketReadyState::Closed) {
- return;
- }
- if (mOpened) {
- if (mReadyState == SocketReadyState::Opening) {
- // reject openedPromise with AbortError if socket is closed without error
- nsresult openFailedReason = NS_FAILED(aReason) ? aReason : NS_ERROR_DOM_ABORT_ERR;
- mOpened->MaybeReject(openFailedReason);
- }
- }
- mReadyState = SocketReadyState::Closed;
- if (mListenerProxy) {
- mListenerProxy->Disconnect();
- mListenerProxy = nullptr;
- }
- if (mSocket) {
- mSocket->Close();
- mSocket = nullptr;
- }
- if (mSocketChild) {
- mSocketChild->Close();
- mSocketChild = nullptr;
- }
- if (mClosed) {
- if (NS_SUCCEEDED(aReason)) {
- mClosed->MaybeResolveWithUndefined();
- } else {
- mClosed->MaybeReject(aReason);
- }
- }
- mPendingMcastCommands.Clear();
- }
- void
- UDPSocket::JoinMulticastGroup(const nsAString& aMulticastGroupAddress,
- ErrorResult& aRv)
- {
- if (mReadyState == SocketReadyState::Closed) {
- aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return;
- }
- if (mReadyState == SocketReadyState::Opening) {
- MulticastCommand joinCommand(MulticastCommand::Join, aMulticastGroupAddress);
- mPendingMcastCommands.AppendElement(joinCommand);
- return;
- }
- MOZ_ASSERT(mSocket || mSocketChild);
- NS_ConvertUTF16toUTF8 address(aMulticastGroupAddress);
- if (mSocket) {
- MOZ_ASSERT(!mSocketChild);
- aRv = mSocket->JoinMulticast(address, EmptyCString());
- NS_WARNING_ASSERTION(!aRv.Failed(), "JoinMulticast failed");
- return;
- }
- MOZ_ASSERT(mSocketChild);
- aRv = mSocketChild->JoinMulticast(address, EmptyCString());
- NS_WARNING_ASSERTION(!aRv.Failed(), "JoinMulticast failed");
- }
- void
- UDPSocket::LeaveMulticastGroup(const nsAString& aMulticastGroupAddress,
- ErrorResult& aRv)
- {
- if (mReadyState == SocketReadyState::Closed) {
- aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return;
- }
- if (mReadyState == SocketReadyState::Opening) {
- MulticastCommand leaveCommand(MulticastCommand::Leave, aMulticastGroupAddress);
- mPendingMcastCommands.AppendElement(leaveCommand);
- return;
- }
- MOZ_ASSERT(mSocket || mSocketChild);
- nsCString address = NS_ConvertUTF16toUTF8(aMulticastGroupAddress);
- if (mSocket) {
- MOZ_ASSERT(!mSocketChild);
- aRv = mSocket->LeaveMulticast(address, EmptyCString());
- NS_WARNING_ASSERTION(!aRv.Failed(), "mSocket->LeaveMulticast failed");
- return;
- }
- MOZ_ASSERT(mSocketChild);
- aRv = mSocketChild->LeaveMulticast(address, EmptyCString());
- NS_WARNING_ASSERTION(!aRv.Failed(), "mSocketChild->LeaveMulticast failed");
- }
- nsresult
- UDPSocket::DoPendingMcastCommand()
- {
- MOZ_ASSERT(mReadyState == SocketReadyState::Open, "Multicast command can only be executed after socket opened");
- for (uint32_t i = 0; i < mPendingMcastCommands.Length(); ++i) {
- MulticastCommand& command = mPendingMcastCommands[i];
- ErrorResult rv;
- switch (command.mCommand) {
- case MulticastCommand::Join: {
- JoinMulticastGroup(command.mAddress, rv);
- break;
- }
- case MulticastCommand::Leave: {
- LeaveMulticastGroup(command.mAddress, rv);
- break;
- }
- }
- if (NS_WARN_IF(rv.Failed())) {
- return rv.StealNSResult();
- }
- }
- mPendingMcastCommands.Clear();
- return NS_OK;
- }
- 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;
- }
- 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->MaybeResolveWithUndefined();
- return NS_OK;
- }
- nsresult
- UDPSocket::InitRemote(const nsAString& aLocalAddress,
- const uint16_t& aLocalPort)
- {
- nsresult rv;
- nsCOMPtr<nsIUDPSocketChild> sock =
- do_CreateInstance("@mozilla.org/udp-socket-child;1", &rv);
- if (NS_FAILED(rv)) {
- return rv;
- }
- mListenerProxy = new ListenerProxy(this);
- nsCOMPtr<nsIGlobalObject> obj = do_QueryInterface(GetOwner(), &rv);
- if (NS_FAILED(rv)) {
- return rv;
- }
- nsCOMPtr<nsIPrincipal> principal = obj->PrincipalOrNull();
- if (!principal) {
- return NS_ERROR_FAILURE;
- }
- rv = sock->Bind(mListenerProxy,
- principal,
- NS_ConvertUTF16toUTF8(aLocalAddress),
- aLocalPort,
- mAddressReuse,
- mLoopback,
- 0,
- 0);
- if (NS_FAILED(rv)) {
- return rv;
- }
- mSocketChild = sock;
- return NS_OK;
- }
- nsresult
- UDPSocket::Init(const nsString& aLocalAddress,
- const Nullable<uint16_t>& aLocalPort,
- const bool& aAddressReuse,
- const bool& aLoopback)
- {
- MOZ_ASSERT(!mSocket && !mSocketChild);
- mLocalAddress = aLocalAddress;
- mLocalPort = aLocalPort;
- mAddressReuse = aAddressReuse;
- mLoopback = aLoopback;
- ErrorResult rv;
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
- mOpened = Promise::Create(global, rv);
- if (NS_WARN_IF(rv.Failed())) {
- return rv.StealNSResult();
- }
- mClosed = Promise::Create(global, rv);
- if (NS_WARN_IF(rv.Failed())) {
- return rv.StealNSResult();
- }
- class OpenSocketRunnable final : public Runnable
- {
- public:
- explicit OpenSocketRunnable(UDPSocket* aSocket) : mSocket(aSocket)
- { }
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(mSocket);
- if (mSocket->mReadyState != SocketReadyState::Opening) {
- return NS_OK;
- }
- uint16_t localPort = 0;
- if (!mSocket->mLocalPort.IsNull()) {
- localPort = mSocket->mLocalPort.Value();
- }
- nsresult rv;
- if (!XRE_IsParentProcess()) {
- rv = mSocket->InitRemote(mSocket->mLocalAddress, localPort);
- } else {
- rv = mSocket->InitLocal(mSocket->mLocalAddress, localPort);
- }
- if (NS_WARN_IF(NS_FAILED(rv))) {
- mSocket->CloseWithReason(NS_ERROR_DOM_NETWORK_ERR);
- }
- return NS_OK;
- }
- private:
- RefPtr<UDPSocket> mSocket;
- };
- nsCOMPtr<nsIRunnable> runnable = new OpenSocketRunnable(this);
- return NS_DispatchToMainThread(runnable);
- }
- void
- UDPSocket::HandleReceivedData(const nsACString& aRemoteAddress,
- const uint16_t& aRemotePort,
- const uint8_t* aData,
- const uint32_t& aDataLength)
- {
- if (mReadyState != SocketReadyState::Open) {
- return;
- }
- if (NS_FAILED(CheckInnerWindowCorrectness())) {
- return;
- }
- if (NS_FAILED(DispatchReceivedData(aRemoteAddress, aRemotePort, aData, aDataLength))) {
- CloseWithReason(NS_ERROR_TYPE_ERR);
- }
- }
- nsresult
- UDPSocket::DispatchReceivedData(const nsACString& aRemoteAddress,
- const uint16_t& aRemotePort,
- const uint8_t* aData,
- const uint32_t& aDataLength)
- {
- AutoJSAPI jsapi;
- if (NS_WARN_IF(!jsapi.Init(GetOwner()))) {
- return NS_ERROR_FAILURE;
- }
- JSContext* cx = jsapi.cx();
- // Copy packet data to ArrayBuffer
- JS::Rooted<JSObject*> arrayBuf(cx, ArrayBuffer::Create(cx, aDataLength, aData));
- if (NS_WARN_IF(!arrayBuf)) {
- return NS_ERROR_FAILURE;
- }
- JS::Rooted<JS::Value> jsData(cx, JS::ObjectValue(*arrayBuf));
- // Create DOM event
- RootedDictionary<UDPMessageEventInit> init(cx);
- init.mRemoteAddress = NS_ConvertUTF8toUTF16(aRemoteAddress);
- init.mRemotePort = aRemotePort;
- init.mData = jsData;
- RefPtr<UDPMessageEvent> udpEvent =
- UDPMessageEvent::Constructor(this, NS_LITERAL_STRING("message"), init);
- if (NS_WARN_IF(!udpEvent)) {
- return NS_ERROR_FAILURE;
- }
- udpEvent->SetTrusted(true);
- RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(this, udpEvent);
- return asyncDispatcher->PostDOMEvent();
- }
- // nsIUDPSocketListener
- NS_IMETHODIMP
- UDPSocket::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
- {
- // nsIUDPSocketListener callbacks should be invoked on main thread.
- MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
- // Create appropriate JS object for message
- FallibleTArray<uint8_t>& buffer = aMessage->GetDataAsTArray();
- nsCOMPtr<nsINetAddr> addr;
- if (NS_WARN_IF(NS_FAILED(aMessage->GetFromAddr(getter_AddRefs(addr))))) {
- return NS_OK;
- }
- nsCString remoteAddress;
- if (NS_WARN_IF(NS_FAILED(addr->GetAddress(remoteAddress)))) {
- return NS_OK;
- }
- uint16_t remotePort;
- if (NS_WARN_IF(NS_FAILED(addr->GetPort(&remotePort)))) {
- return NS_OK;
- }
- HandleReceivedData(remoteAddress, remotePort, buffer.Elements(), buffer.Length());
- return NS_OK;
- }
- NS_IMETHODIMP
- UDPSocket::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
- {
- // nsIUDPSocketListener callbacks should be invoked on main thread.
- MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
- CloseWithReason(aStatus);
- return NS_OK;
- }
- // nsIUDPSocketInternal
- NS_IMETHODIMP
- UDPSocket::CallListenerError(const nsACString& aMessage,
- const nsACString& aFilename,
- uint32_t aLineNumber)
- {
- CloseWithReason(NS_ERROR_DOM_NETWORK_ERR);
- return NS_OK;
- }
- NS_IMETHODIMP
- UDPSocket::CallListenerReceivedData(const nsACString& aRemoteAddress,
- uint16_t aRemotePort,
- const uint8_t* aData,
- uint32_t aDataLength)
- {
- HandleReceivedData(aRemoteAddress, aRemotePort, aData, aDataLength);
- return NS_OK;
- }
- NS_IMETHODIMP
- UDPSocket::CallListenerOpened()
- {
- if (mReadyState != SocketReadyState::Opening) {
- return NS_OK;
- }
- MOZ_ASSERT(mSocketChild);
- // Get real local address and local port
- nsCString localAddress;
- mSocketChild->GetLocalAddress(localAddress);
- mLocalAddress = NS_ConvertUTF8toUTF16(localAddress);
- uint16_t localPort;
- mSocketChild->GetLocalPort(&localPort);
- mLocalPort.SetValue(localPort);
- mReadyState = SocketReadyState::Open;
- nsresult rv = DoPendingMcastCommand();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- CloseWithReason(rv);
- return NS_OK;
- }
- mOpened->MaybeResolveWithUndefined();
- return NS_OK;
- }
- NS_IMETHODIMP
- UDPSocket::CallListenerConnected()
- {
- // This shouldn't be called here.
- MOZ_CRASH();
- return NS_OK;
- }
- NS_IMETHODIMP
- UDPSocket::CallListenerClosed()
- {
- CloseWithReason(NS_OK);
- return NS_OK;
- }
- } // namespace dom
- } // namespace mozilla
|