Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "UDPSocketChild.h"
6 #include "mozilla/net/NeckoChild.h"
8 using mozilla::net::gNeckoChild;
10 namespace mozilla {
11 namespace dom {
13 NS_IMPL_ISUPPORTS(UDPSocketChildBase, nsIUDPSocketChild)
15 UDPSocketChildBase::UDPSocketChildBase()
16 : mIPCOpen(false)
17 {
18 }
20 UDPSocketChildBase::~UDPSocketChildBase()
21 {
22 }
24 void
25 UDPSocketChildBase::ReleaseIPDLReference()
26 {
27 MOZ_ASSERT(mIPCOpen);
28 mIPCOpen = false;
29 this->Release();
30 }
32 void
33 UDPSocketChildBase::AddIPDLReference()
34 {
35 MOZ_ASSERT(!mIPCOpen);
36 mIPCOpen = true;
37 this->AddRef();
38 }
40 NS_IMETHODIMP_(MozExternalRefCountType) UDPSocketChild::Release(void)
41 {
42 nsrefcnt refcnt = UDPSocketChildBase::Release();
43 if (refcnt == 1 && mIPCOpen) {
44 PUDPSocketChild::SendRequestDelete();
45 return 1;
46 }
47 return refcnt;
48 }
50 UDPSocketChild::UDPSocketChild()
51 :mLocalPort(0)
52 {
53 }
55 UDPSocketChild::~UDPSocketChild()
56 {
57 }
59 // nsIUDPSocketChild Methods
61 NS_IMETHODIMP
62 UDPSocketChild::Bind(nsIUDPSocketInternal *aSocket,
63 const nsACString& aHost,
64 uint16_t aPort)
65 {
66 NS_ENSURE_ARG(aSocket);
68 mSocket = aSocket;
69 AddIPDLReference();
71 gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort, mFilterName);
73 return NS_OK;
74 }
76 NS_IMETHODIMP
77 UDPSocketChild::Close()
78 {
79 SendClose();
80 return NS_OK;
81 }
83 NS_IMETHODIMP
84 UDPSocketChild::Send(const nsACString& aHost,
85 uint16_t aPort,
86 const uint8_t *aData,
87 uint32_t aByteLength)
88 {
89 NS_ENSURE_ARG(aData);
91 FallibleTArray<uint8_t> fallibleArray;
92 if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
93 return NS_ERROR_OUT_OF_MEMORY;
94 }
96 InfallibleTArray<uint8_t> array;
97 array.SwapElements(fallibleArray);
98 SendData(array, nsCString(aHost), aPort);
100 return NS_OK;
101 }
103 NS_IMETHODIMP
104 UDPSocketChild::SendWithAddr(nsINetAddr *aAddr,
105 const uint8_t *aData,
106 uint32_t aByteLength)
107 {
108 NS_ENSURE_ARG(aAddr);
109 NS_ENSURE_ARG(aData);
111 NetAddr addr;
112 aAddr->GetNetAddr(&addr);
114 return SendWithAddress(&addr, aData, aByteLength);
115 }
117 NS_IMETHODIMP
118 UDPSocketChild::SendWithAddress(const NetAddr *aAddr,
119 const uint8_t *aData,
120 uint32_t aByteLength)
121 {
122 NS_ENSURE_ARG(aAddr);
123 NS_ENSURE_ARG(aData);
125 FallibleTArray<uint8_t> fallibleArray;
126 if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
127 return NS_ERROR_OUT_OF_MEMORY;
128 }
130 InfallibleTArray<uint8_t> array;
131 array.SwapElements(fallibleArray);
132 SendDataWithAddress(array, *aAddr);
134 return NS_OK;
135 }
137 NS_IMETHODIMP
138 UDPSocketChild::GetLocalPort(uint16_t *aLocalPort)
139 {
140 NS_ENSURE_ARG_POINTER(aLocalPort);
142 *aLocalPort = mLocalPort;
143 return NS_OK;
144 }
146 NS_IMETHODIMP
147 UDPSocketChild::GetLocalAddress(nsACString &aLocalAddress)
148 {
149 aLocalAddress = mLocalAddress;
150 return NS_OK;
151 }
153 NS_IMETHODIMP
154 UDPSocketChild::SetFilterName(const nsACString &aFilterName)
155 {
156 if (!mFilterName.IsEmpty()) {
157 // filter name can only be set once.
158 return NS_ERROR_FAILURE;
159 }
160 mFilterName = aFilterName;
161 return NS_OK;
162 }
164 NS_IMETHODIMP
165 UDPSocketChild::GetFilterName(nsACString &aFilterName)
166 {
167 aFilterName = mFilterName;
168 return NS_OK;
169 }
171 // PUDPSocketChild Methods
172 bool
173 UDPSocketChild::RecvCallback(const nsCString &aType,
174 const UDPCallbackData &aData,
175 const nsCString &aState)
176 {
177 if (NS_FAILED(mSocket->UpdateReadyState(aState)))
178 NS_ERROR("Shouldn't fail!");
180 nsresult rv = NS_ERROR_FAILURE;
181 if (aData.type() == UDPCallbackData::Tvoid_t) {
182 rv = mSocket->CallListenerVoid(aType);
183 } else if (aData.type() == UDPCallbackData::TUDPError) {
184 const UDPError& err(aData.get_UDPError());
185 rv = mSocket->CallListenerError(aType, err.message(), err.filename(),
186 err.lineNumber(), err.columnNumber());
187 } else if (aData.type() == UDPCallbackData::TUDPMessage) {
188 const UDPMessage& message(aData.get_UDPMessage());
189 InfallibleTArray<uint8_t> data(message.data());
190 rv = mSocket->CallListenerReceivedData(aType, message.fromAddr(), message.port(),
191 data.Elements(), data.Length());
192 } else if (aData.type() == UDPCallbackData::TUDPAddressInfo) {
193 //update local address and port.
194 const UDPAddressInfo& addressInfo(aData.get_UDPAddressInfo());
195 mLocalAddress = addressInfo.local();
196 mLocalPort = addressInfo.port();
197 rv = mSocket->CallListenerVoid(aType);
198 } else if (aData.type() == UDPCallbackData::TUDPSendResult) {
199 const UDPSendResult& returnValue(aData.get_UDPSendResult());
200 rv = mSocket->CallListenerSent(aType, returnValue.value());
201 } else {
202 MOZ_ASSERT(false, "Invalid callback type!");
203 }
205 NS_ENSURE_SUCCESS(rv, true);
207 return true;
208 }
210 } // namespace dom
211 } // namespace mozilla