summaryrefslogtreecommitdiffstats
path: root/dom/network/UDPSocket.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/network/UDPSocket.h')
-rw-r--r--dom/network/UDPSocket.h232
1 files changed, 232 insertions, 0 deletions
diff --git a/dom/network/UDPSocket.h b/dom/network/UDPSocket.h
new file mode 100644
index 000000000..12427d1dd
--- /dev/null
+++ b/dom/network/UDPSocket.h
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_UDPSocket_h__
+#define mozilla_dom_UDPSocket_h__
+
+#include "mozilla/Attributes.h"
+#include "mozilla/DOMEventTargetHelper.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/Promise.h"
+#include "mozilla/dom/SocketCommonBinding.h"
+#include "nsIUDPSocket.h"
+#include "nsIUDPSocketChild.h"
+#include "nsTArray.h"
+
+struct JSContext;
+
+//
+// set MOZ_LOG=UDPSocket:5
+//
+
+namespace mozilla {
+namespace net {
+extern LazyLogModule gUDPSocketLog;
+#define UDPSOCKET_LOG(args) MOZ_LOG(gUDPSocketLog, LogLevel::Debug, args)
+#define UDPSOCKET_LOG_ENABLED() MOZ_LOG_TEST(gUDPSocketLog, LogLevel::Debug)
+} // namespace net
+
+namespace dom {
+
+struct UDPOptions;
+class StringOrBlobOrArrayBufferOrArrayBufferView;
+
+class UDPSocket final : public DOMEventTargetHelper
+ , public nsIUDPSocketListener
+ , public nsIUDPSocketInternal
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(UDPSocket, DOMEventTargetHelper)
+ NS_DECL_NSIUDPSOCKETLISTENER
+ NS_DECL_NSIUDPSOCKETINTERNAL
+ NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
+
+public:
+ nsPIDOMWindowInner*
+ GetParentObject() const
+ {
+ return GetOwner();
+ }
+
+ virtual JSObject*
+ WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+ virtual void
+ DisconnectFromOwner() override;
+
+ static already_AddRefed<UDPSocket>
+ Constructor(const GlobalObject& aGlobal, const UDPOptions& aOptions, ErrorResult& aRv);
+
+ void
+ GetLocalAddress(nsString& aRetVal) const
+ {
+ aRetVal = mLocalAddress;
+ }
+
+ Nullable<uint16_t>
+ GetLocalPort() const
+ {
+ return mLocalPort;
+ }
+
+ void
+ GetRemoteAddress(nsString& aRetVal) const
+ {
+ if (mRemoteAddress.IsVoid()) {
+ SetDOMStringToNull(aRetVal);
+ return;
+ }
+
+ aRetVal = NS_ConvertUTF8toUTF16(mRemoteAddress);
+ }
+
+ Nullable<uint16_t>
+ GetRemotePort() const
+ {
+ return mRemotePort;
+ }
+
+ bool
+ AddressReuse() const
+ {
+ return mAddressReuse;
+ }
+
+ bool
+ Loopback() const
+ {
+ return mLoopback;
+ }
+
+ SocketReadyState
+ ReadyState() const
+ {
+ return mReadyState;
+ }
+
+ Promise*
+ Opened() const
+ {
+ return mOpened;
+ }
+
+ Promise*
+ Closed() const
+ {
+ return mClosed;
+ }
+
+ IMPL_EVENT_HANDLER(message)
+
+ already_AddRefed<Promise>
+ Close();
+
+ void
+ JoinMulticastGroup(const nsAString& aMulticastGroupAddress, ErrorResult& aRv);
+
+ void
+ LeaveMulticastGroup(const nsAString& aMulticastGroupAddress, ErrorResult& aRv);
+
+ bool
+ Send(const StringOrBlobOrArrayBufferOrArrayBufferView& aData,
+ const Optional<nsAString>& aRemoteAddress,
+ const Optional<Nullable<uint16_t>>& aRemotePort,
+ ErrorResult& aRv);
+
+private:
+ class ListenerProxy : public nsIUDPSocketListener
+ , public nsIUDPSocketInternal
+ {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_FORWARD_SAFE_NSIUDPSOCKETLISTENER(mSocket)
+ NS_FORWARD_SAFE_NSIUDPSOCKETINTERNAL(mSocket)
+
+ explicit ListenerProxy(UDPSocket* aSocket)
+ : mSocket(aSocket)
+ {
+ }
+
+ void Disconnect()
+ {
+ mSocket = nullptr;
+ }
+
+ private:
+ virtual ~ListenerProxy() {}
+
+ UDPSocket* mSocket;
+ };
+
+ UDPSocket(nsPIDOMWindowInner* aOwner,
+ const nsCString& aRemoteAddress,
+ const Nullable<uint16_t>& aRemotePort);
+
+ virtual ~UDPSocket();
+
+ nsresult
+ Init(const nsString& aLocalAddress,
+ const Nullable<uint16_t>& aLocalPort,
+ const bool& aAddressReuse,
+ const bool& aLoopback);
+
+ nsresult
+ InitLocal(const nsAString& aLocalAddress, const uint16_t& aLocalPort);
+
+ nsresult
+ InitRemote(const nsAString& aLocalAddress, const uint16_t& aLocalPort);
+
+ void
+ HandleReceivedData(const nsACString& aRemoteAddress,
+ const uint16_t& aRemotePort,
+ const uint8_t* aData,
+ const uint32_t& aDataLength);
+
+ nsresult
+ DispatchReceivedData(const nsACString& aRemoteAddress,
+ const uint16_t& aRemotePort,
+ const uint8_t* aData,
+ const uint32_t& aDataLength);
+
+ void
+ CloseWithReason(nsresult aReason);
+
+ nsresult
+ DoPendingMcastCommand();
+
+ nsString mLocalAddress;
+ Nullable<uint16_t> mLocalPort;
+ nsCString mRemoteAddress;
+ Nullable<uint16_t> mRemotePort;
+ bool mAddressReuse;
+ bool mLoopback;
+ SocketReadyState mReadyState;
+ RefPtr<Promise> mOpened;
+ RefPtr<Promise> mClosed;
+
+ nsCOMPtr<nsIUDPSocket> mSocket;
+ nsCOMPtr<nsIUDPSocketChild> mSocketChild;
+ RefPtr<ListenerProxy> mListenerProxy;
+
+ struct MulticastCommand {
+ enum CommandType { Join, Leave };
+
+ MulticastCommand(CommandType aCommand, const nsAString& aAddress)
+ : mCommand(aCommand), mAddress(aAddress)
+ { }
+
+ CommandType mCommand;
+ nsString mAddress;
+ };
+
+ nsTArray<MulticastCommand> mPendingMcastCommands;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_UDPSocket_h__