1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_UDPSocket_h__ 8 #define mozilla_dom_UDPSocket_h__ 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/DOMEventTargetHelper.h" 12 #include "mozilla/dom/Promise.h" 13 #include "mozilla/dom/SocketCommonBinding.h" 14 #include "nsIUDPSocket.h" 15 #include "nsIUDPSocketChild.h" 16 #include "nsTArray.h" 17 18 struct JSContext; 19 20 // 21 // set MOZ_LOG=UDPSocket:5 22 // 23 24 namespace mozilla { 25 class ErrorResult; 26 class LazyLogModule; 27 28 namespace net { 29 extern LazyLogModule gUDPSocketLog; 30 #define UDPSOCKET_LOG(args) \ 31 MOZ_LOG(::mozilla::net::gUDPSocketLog, LogLevel::Debug, args) 32 #define UDPSOCKET_LOG_ENABLED() \ 33 MOZ_LOG_TEST(::mozilla::net::gUDPSocketLog, LogLevel::Debug) 34 } // namespace net 35 36 namespace dom { 37 38 struct UDPOptions; 39 class StringOrBlobOrArrayBufferOrArrayBufferView; 40 class UDPSocketChild; 41 42 class UDPSocket final : public DOMEventTargetHelper, 43 public nsIUDPSocketListener, 44 public nsIUDPSocketInternal { 45 public: 46 NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(UDPSocket,DOMEventTargetHelper)47 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(UDPSocket, DOMEventTargetHelper) 48 NS_DECL_NSIUDPSOCKETLISTENER 49 NS_DECL_NSIUDPSOCKETINTERNAL 50 51 public: 52 nsPIDOMWindowInner* GetParentObject() const { return GetOwner(); } 53 54 virtual JSObject* WrapObject(JSContext* aCx, 55 JS::Handle<JSObject*> aGivenProto) override; 56 57 virtual void DisconnectFromOwner() override; 58 59 static already_AddRefed<UDPSocket> Constructor(const GlobalObject& aGlobal, 60 const UDPOptions& aOptions, 61 ErrorResult& aRv); 62 GetLocalAddress(nsString & aRetVal)63 void GetLocalAddress(nsString& aRetVal) const { aRetVal = mLocalAddress; } 64 GetLocalPort()65 Nullable<uint16_t> GetLocalPort() const { return mLocalPort; } 66 GetRemoteAddress(nsString & aRetVal)67 void GetRemoteAddress(nsString& aRetVal) const { 68 if (mRemoteAddress.IsVoid()) { 69 SetDOMStringToNull(aRetVal); 70 return; 71 } 72 73 CopyUTF8toUTF16(mRemoteAddress, aRetVal); 74 } 75 GetRemotePort()76 Nullable<uint16_t> GetRemotePort() const { return mRemotePort; } 77 AddressReuse()78 bool AddressReuse() const { return mAddressReuse; } 79 Loopback()80 bool Loopback() const { return mLoopback; } 81 ReadyState()82 SocketReadyState ReadyState() const { return mReadyState; } 83 Opened()84 Promise* Opened() const { return mOpened; } 85 Closed()86 Promise* Closed() const { return mClosed; } 87 88 IMPL_EVENT_HANDLER(message) 89 90 already_AddRefed<Promise> Close(); 91 92 void JoinMulticastGroup(const nsAString& aMulticastGroupAddress, 93 ErrorResult& aRv); 94 95 void LeaveMulticastGroup(const nsAString& aMulticastGroupAddress, 96 ErrorResult& aRv); 97 98 bool Send(const StringOrBlobOrArrayBufferOrArrayBufferView& aData, 99 const Optional<nsAString>& aRemoteAddress, 100 const Optional<Nullable<uint16_t>>& aRemotePort, ErrorResult& aRv); 101 102 private: 103 class ListenerProxy : public nsIUDPSocketListener, 104 public nsIUDPSocketInternal { 105 public: 106 NS_DECL_ISUPPORTS NS_FORWARD_SAFE_NSIUDPSOCKETLISTENER(mSocket)107 NS_FORWARD_SAFE_NSIUDPSOCKETLISTENER(mSocket) 108 NS_FORWARD_SAFE_NSIUDPSOCKETINTERNAL(mSocket) 109 110 explicit ListenerProxy(UDPSocket* aSocket) : mSocket(aSocket) {} 111 Disconnect()112 void Disconnect() { mSocket = nullptr; } 113 114 private: 115 virtual ~ListenerProxy() = default; 116 117 UDPSocket* mSocket; 118 }; 119 120 UDPSocket(nsPIDOMWindowInner* aOwner, const nsCString& aRemoteAddress, 121 const Nullable<uint16_t>& aRemotePort); 122 123 virtual ~UDPSocket(); 124 125 nsresult Init(const nsString& aLocalAddress, 126 const Nullable<uint16_t>& aLocalPort, const bool& aAddressReuse, 127 const bool& aLoopback); 128 129 nsresult InitLocal(const nsAString& aLocalAddress, 130 const uint16_t& aLocalPort); 131 132 nsresult InitRemote(const nsAString& aLocalAddress, 133 const uint16_t& aLocalPort); 134 135 void HandleReceivedData(const nsACString& aRemoteAddress, 136 const uint16_t& aRemotePort, 137 const nsTArray<uint8_t>& aData); 138 139 nsresult DispatchReceivedData(const nsACString& aRemoteAddress, 140 const uint16_t& aRemotePort, 141 const nsTArray<uint8_t>& aData); 142 143 void CloseWithReason(nsresult aReason); 144 145 nsresult DoPendingMcastCommand(); 146 147 nsString mLocalAddress; 148 Nullable<uint16_t> mLocalPort; 149 nsCString mRemoteAddress; 150 Nullable<uint16_t> mRemotePort; 151 bool mAddressReuse; 152 bool mLoopback; 153 SocketReadyState mReadyState; 154 RefPtr<Promise> mOpened; 155 RefPtr<Promise> mClosed; 156 157 nsCOMPtr<nsIUDPSocket> mSocket; 158 RefPtr<UDPSocketChild> mSocketChild; 159 RefPtr<ListenerProxy> mListenerProxy; 160 161 struct MulticastCommand { 162 enum CommandType { Join, Leave }; 163 MulticastCommandMulticastCommand164 MulticastCommand(CommandType aCommand, const nsAString& aAddress) 165 : mCommand(aCommand), mAddress(aAddress) {} 166 167 CommandType mCommand; 168 nsString mAddress; 169 }; 170 171 nsTArray<MulticastCommand> mPendingMcastCommands; 172 }; 173 174 } // namespace dom 175 } // namespace mozilla 176 177 #endif // mozilla_dom_UDPSocket_h__ 178