Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/network/UDPSocketParent.cpp
Line
Count
Source (jump to first uncovered line)
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nsIServiceManager.h"
8
#include "UDPSocketParent.h"
9
#include "nsComponentManagerUtils.h"
10
#include "nsIUDPSocket.h"
11
#include "nsINetAddr.h"
12
#include "mozilla/Unused.h"
13
#include "mozilla/ipc/InputStreamUtils.h"
14
#include "mozilla/net/DNS.h"
15
#include "mozilla/net/NeckoCommon.h"
16
#include "mozilla/net/PNeckoParent.h"
17
#include "nsIPermissionManager.h"
18
#include "nsIScriptSecurityManager.h"
19
#include "mozilla/ipc/PBackgroundParent.h"
20
#include "mtransport/runnable_utils.h"
21
22
namespace mozilla {
23
24
using namespace net;
25
26
namespace dom {
27
28
NS_IMPL_ISUPPORTS(UDPSocketParent, nsIUDPSocketListener)
29
30
UDPSocketParent::UDPSocketParent(PBackgroundParent* aManager)
31
  : mBackgroundManager(aManager)
32
  , mIPCOpen(true)
33
0
{
34
0
}
35
36
UDPSocketParent::UDPSocketParent(PNeckoParent* aManager)
37
  : mBackgroundManager(nullptr)
38
  , mIPCOpen(true)
39
0
{
40
0
}
41
42
UDPSocketParent::~UDPSocketParent()
43
0
{
44
0
}
45
46
bool
47
UDPSocketParent::Init(const IPC::Principal& aPrincipal,
48
                      const nsACString& aFilter)
49
0
{
50
0
  MOZ_ASSERT_IF(mBackgroundManager, !aPrincipal);
51
0
  // will be used once we move all UDPSocket to PBackground, or
52
0
  // if we add in Principal checking for mtransport
53
0
  Unused << mBackgroundManager;
54
0
55
0
  mPrincipal = aPrincipal;
56
0
  if (net::UsingNeckoIPCSecurity() &&
57
0
      mPrincipal &&
58
0
      !ContentParent::IgnoreIPCPrincipal()) {
59
0
    nsCOMPtr<nsIPermissionManager> permMgr =
60
0
      services::GetPermissionManager();
61
0
    if (!permMgr) {
62
0
      NS_WARNING("No PermissionManager available!");
63
0
      return false;
64
0
    }
65
0
66
0
    uint32_t permission = nsIPermissionManager::DENY_ACTION;
67
0
    permMgr->TestExactPermissionFromPrincipal(mPrincipal, "udp-socket",
68
0
                                              &permission);
69
0
    if (permission != nsIPermissionManager::ALLOW_ACTION) {
70
0
      return false;
71
0
    }
72
0
  }
73
0
74
0
  if (!aFilter.IsEmpty()) {
75
0
    nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
76
0
    contractId.Append(aFilter);
77
0
    nsCOMPtr<nsISocketFilterHandler> filterHandler =
78
0
      do_GetService(contractId.get());
79
0
    if (filterHandler) {
80
0
      nsresult rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
81
0
      if (NS_FAILED(rv)) {
82
0
        printf_stderr("Cannot create filter that content specified. "
83
0
                      "filter name: %s, error code: %u.", aFilter.BeginReading(),  static_cast<uint32_t>(rv));
84
0
        return false;
85
0
      }
86
0
    } else {
87
0
      printf_stderr("Content doesn't have a valid filter. "
88
0
                    "filter name: %s.", aFilter.BeginReading());
89
0
      return false;
90
0
    }
91
0
  }
92
0
  // We don't have browser actors in xpcshell, and hence can't run automated
93
0
  // tests without this loophole.
94
0
  if (net::UsingNeckoIPCSecurity() && !mFilter &&
95
0
      (!mPrincipal || ContentParent::IgnoreIPCPrincipal())) {
96
0
    return false;
97
0
  }
98
0
  return true;
99
0
}
100
101
// PUDPSocketParent methods
102
103
mozilla::ipc::IPCResult
104
UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
105
                          const bool& aAddressReuse, const bool& aLoopback,
106
                          const uint32_t& recvBufferSize,
107
                          const uint32_t& sendBufferSize)
108
0
{
109
0
  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
110
0
111
0
  if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(),
112
0
                             aAddressReuse, aLoopback, recvBufferSize,
113
0
                             sendBufferSize))) {
114
0
    FireInternalError(__LINE__);
115
0
    return IPC_OK();
116
0
  }
117
0
118
0
  nsCOMPtr<nsINetAddr> localAddr;
119
0
  mSocket->GetLocalAddr(getter_AddRefs(localAddr));
120
0
121
0
  nsCString addr;
122
0
  if (NS_FAILED(localAddr->GetAddress(addr))) {
123
0
    FireInternalError(__LINE__);
124
0
    return IPC_OK();
125
0
  }
126
0
127
0
  uint16_t port;
128
0
  if (NS_FAILED(localAddr->GetPort(&port))) {
129
0
    FireInternalError(__LINE__);
130
0
    return IPC_OK();
131
0
  }
132
0
133
0
  UDPSOCKET_LOG(("%s: SendCallbackOpened: %s:%u", __FUNCTION__, addr.get(), port));
134
0
  mozilla::Unused << SendCallbackOpened(UDPAddressInfo(addr, port));
135
0
136
0
  return IPC_OK();
137
0
}
138
139
nsresult
140
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
141
                              const bool& aAddressReuse, const bool& aLoopback,
142
                              const uint32_t& recvBufferSize,
143
                              const uint32_t& sendBufferSize)
144
0
{
145
0
  nsresult rv;
146
0
147
0
  UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %"
148
0
                 PRIu32 ", sendBufferSize: %" PRIu32,
149
0
                __FUNCTION__, this, nsCString(aHost).get(), aPort,
150
0
                aAddressReuse, aLoopback, recvBufferSize, sendBufferSize));
151
0
152
0
  nsCOMPtr<nsIUDPSocket> sock =
153
0
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
154
0
155
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
156
0
    return rv;
157
0
  }
158
0
159
0
  if (aHost.IsEmpty()) {
160
0
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
161
0
                    /* optional_argc = */ 1);
162
0
  } else {
163
0
    PRNetAddr prAddr;
164
0
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
165
0
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
166
0
    if (status != PR_SUCCESS) {
167
0
      return NS_ERROR_FAILURE;
168
0
    }
169
0
170
0
    mozilla::net::NetAddr addr;
171
0
    PRNetAddrToNetAddr(&prAddr, &addr);
172
0
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
173
0
                               /* optional_argc = */ 1);
174
0
  }
175
0
176
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
177
0
    return rv;
178
0
  }
179
0
180
0
  nsCOMPtr<nsINetAddr> laddr;
181
0
  rv = sock->GetLocalAddr(getter_AddRefs(laddr));
182
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
183
0
    return rv;
184
0
  }
185
0
  uint16_t family;
186
0
  rv = laddr->GetFamily(&family);
187
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
188
0
    return rv;
189
0
  }
190
0
  if (family == nsINetAddr::FAMILY_INET) {
191
0
    rv = sock->SetMulticastLoopback(aLoopback);
192
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
193
0
      return rv;
194
0
    }
195
0
  }
196
0
  // TODO: once bug 1252759 is fixed query buffer first and only increase
197
0
  if (recvBufferSize != 0) {
198
0
    rv = sock->SetRecvBufferSize(recvBufferSize);
199
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
200
0
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize));
201
0
    }
202
0
  }
203
0
  if (sendBufferSize != 0) {
204
0
    rv = sock->SetSendBufferSize(sendBufferSize);
205
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
206
0
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set send buffer size to: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, sendBufferSize));
207
0
    }
208
0
  }
209
0
210
0
  // register listener
211
0
  rv = sock->AsyncListen(this);
212
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
213
0
    return rv;
214
0
  }
215
0
216
0
  mSocket = sock;
217
0
218
0
  return NS_OK;
219
0
}
220
221
222
static nsCOMPtr<nsIEventTarget> GetSTSThread()
223
0
{
224
0
  nsresult rv;
225
0
226
0
  nsCOMPtr<nsIEventTarget> sts_thread;
227
0
228
0
  sts_thread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
229
0
  MOZ_ASSERT(NS_SUCCEEDED(rv));
230
0
231
0
  return sts_thread;
232
0
}
233
234
static void CheckSTSThread()
235
0
{
236
0
  DebugOnly<nsCOMPtr<nsIEventTarget>> sts_thread = GetSTSThread();
237
0
238
0
  ASSERT_ON_THREAD(sts_thread.value);
239
0
}
240
241
242
// Proxy the Connect() request to the STS thread, since it may block and
243
// should be done there.
244
mozilla::ipc::IPCResult
245
UDPSocketParent::RecvConnect(const UDPAddressInfo& aAddressInfo)
246
0
{
247
0
  nsCOMPtr<nsIEventTarget> target = GetCurrentThreadEventTarget();
248
0
  Unused <<
249
0
    NS_WARN_IF(NS_FAILED(GetSTSThread()->Dispatch(WrapRunnable(
250
0
                                                    RefPtr<UDPSocketParent>(this),
251
0
                                                    &UDPSocketParent::DoConnect,
252
0
                                                    mSocket,
253
0
                                                    target,
254
0
                                                    aAddressInfo),
255
0
                                                  NS_DISPATCH_NORMAL)));
256
0
  return IPC_OK();
257
0
}
258
259
void
260
UDPSocketParent::DoSendConnectResponse(const UDPAddressInfo& aAddressInfo)
261
0
{
262
0
  // can't use directly with WrapRunnable due to warnings
263
0
  mozilla::Unused << SendCallbackConnected(aAddressInfo);
264
0
}
265
266
void
267
UDPSocketParent::SendConnectResponse(nsIEventTarget *aThread,
268
                                     const UDPAddressInfo& aAddressInfo)
269
0
{
270
0
  Unused <<
271
0
    NS_WARN_IF(NS_FAILED(aThread->Dispatch(WrapRunnable(
272
0
                                             RefPtr<UDPSocketParent>(this),
273
0
                                             &UDPSocketParent::DoSendConnectResponse,
274
0
                                             aAddressInfo),
275
0
                                           NS_DISPATCH_NORMAL)));
276
0
}
277
278
// Runs on STS thread
279
void
280
UDPSocketParent::DoConnect(nsCOMPtr<nsIUDPSocket>& aSocket,
281
                           nsCOMPtr<nsIEventTarget>& aReturnThread,
282
                           const UDPAddressInfo& aAddressInfo)
283
0
{
284
0
  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
285
0
  if (NS_FAILED(ConnectInternal(aAddressInfo.addr(), aAddressInfo.port()))) {
286
0
    SendInternalError(aReturnThread, __LINE__);
287
0
    return;
288
0
  }
289
0
  CheckSTSThread();
290
0
291
0
  nsCOMPtr<nsINetAddr> localAddr;
292
0
  aSocket->GetLocalAddr(getter_AddRefs(localAddr));
293
0
294
0
  nsCString addr;
295
0
  if (NS_FAILED(localAddr->GetAddress(addr))) {
296
0
    SendInternalError(aReturnThread, __LINE__);
297
0
    return;
298
0
  }
299
0
300
0
  uint16_t port;
301
0
  if (NS_FAILED(localAddr->GetPort(&port))) {
302
0
    SendInternalError(aReturnThread, __LINE__);
303
0
    return;
304
0
  }
305
0
306
0
  UDPSOCKET_LOG(("%s: SendConnectResponse: %s:%u", __FUNCTION__, addr.get(), port));
307
0
  SendConnectResponse(aReturnThread, UDPAddressInfo(addr, port));
308
0
}
309
310
nsresult
311
UDPSocketParent::ConnectInternal(const nsCString& aHost, const uint16_t& aPort)
312
0
{
313
0
  nsresult rv;
314
0
315
0
  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));
316
0
317
0
  if (!mSocket) {
318
0
    return NS_ERROR_NOT_AVAILABLE;
319
0
  }
320
0
321
0
  PRNetAddr prAddr;
322
0
  memset(&prAddr, 0, sizeof(prAddr));
323
0
  PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
324
0
  PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
325
0
  if (status != PR_SUCCESS) {
326
0
    return NS_ERROR_FAILURE;
327
0
  }
328
0
329
0
  mozilla::net::NetAddr addr;
330
0
  PRNetAddrToNetAddr(&prAddr, &addr);
331
0
332
0
  rv = mSocket->Connect(&addr);
333
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
334
0
    return rv;
335
0
  }
336
0
337
0
  return NS_OK;
338
0
}
339
340
mozilla::ipc::IPCResult
341
UDPSocketParent::RecvOutgoingData(const UDPData& aData,
342
                                  const UDPSocketAddr& aAddr)
343
0
{
344
0
  if (!mSocket) {
345
0
    NS_WARNING("sending socket is closed");
346
0
    FireInternalError(__LINE__);
347
0
    return IPC_OK();
348
0
  }
349
0
350
0
  nsresult rv;
351
0
  if (mFilter) {
352
0
    if (aAddr.type() != UDPSocketAddr::TNetAddr) {
353
0
      return IPC_OK();
354
0
    }
355
0
356
0
    // TODO, Packet filter doesn't support input stream yet.
357
0
    if (aData.type() != UDPData::TArrayOfuint8_t) {
358
0
      return IPC_OK();
359
0
    }
360
0
361
0
    bool allowed;
362
0
    const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t());
363
0
    rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(),
364
0
                               data.Length(), nsISocketFilter::SF_OUTGOING,
365
0
                               &allowed);
366
0
367
0
    // Sending unallowed data, kill content.
368
0
    if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
369
0
      return IPC_FAIL(this, "Content tried to send non STUN packet");
370
0
    }
371
0
  }
372
0
373
0
  switch(aData.type()) {
374
0
    case UDPData::TArrayOfuint8_t:
375
0
      Send(aData.get_ArrayOfuint8_t(), aAddr);
376
0
      break;
377
0
    case UDPData::TIPCStream:
378
0
      Send(aData.get_IPCStream(), aAddr);
379
0
      break;
380
0
    default:
381
0
      MOZ_ASSERT(false, "Invalid data type!");
382
0
      return IPC_OK();
383
0
  }
384
0
385
0
  return IPC_OK();
386
0
}
387
388
void
389
UDPSocketParent::Send(const InfallibleTArray<uint8_t>& aData,
390
                      const UDPSocketAddr& aAddr)
391
0
{
392
0
  nsresult rv;
393
0
  uint32_t count;
394
0
  switch(aAddr.type()) {
395
0
    case UDPSocketAddr::TUDPAddressInfo: {
396
0
      const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
397
0
      rv = mSocket->Send(addrInfo.addr(), addrInfo.port(),
398
0
                         aData.Elements(), aData.Length(), &count);
399
0
      break;
400
0
    }
401
0
    case UDPSocketAddr::TNetAddr: {
402
0
      const NetAddr& addr(aAddr.get_NetAddr());
403
0
      rv = mSocket->SendWithAddress(&addr, aData.Elements(),
404
0
                                    aData.Length(), &count);
405
0
      break;
406
0
    }
407
0
    default:
408
0
      MOZ_ASSERT(false, "Invalid address type!");
409
0
      return;
410
0
  }
411
0
412
0
  if (NS_WARN_IF(NS_FAILED(rv)) || count == 0) {
413
0
    FireInternalError(__LINE__);
414
0
  }
415
0
}
416
417
void
418
UDPSocketParent::Send(const IPCStream& aStream,
419
                      const UDPSocketAddr& aAddr)
420
0
{
421
0
  nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);
422
0
423
0
  if (NS_WARN_IF(!stream)) {
424
0
    return;
425
0
  }
426
0
427
0
  nsresult rv;
428
0
  switch(aAddr.type()) {
429
0
    case UDPSocketAddr::TUDPAddressInfo: {
430
0
      const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
431
0
      rv = mSocket->SendBinaryStream(addrInfo.addr(), addrInfo.port(), stream);
432
0
      break;
433
0
    }
434
0
    case UDPSocketAddr::TNetAddr: {
435
0
      const NetAddr& addr(aAddr.get_NetAddr());
436
0
      rv = mSocket->SendBinaryStreamWithAddress(&addr, stream);
437
0
      break;
438
0
    }
439
0
    default:
440
0
      MOZ_ASSERT(false, "Invalid address type!");
441
0
      return;
442
0
  }
443
0
444
0
  if (NS_FAILED(rv)) {
445
0
    FireInternalError(__LINE__);
446
0
  }
447
0
}
448
449
mozilla::ipc::IPCResult
450
UDPSocketParent::RecvJoinMulticast(const nsCString& aMulticastAddress,
451
                                   const nsCString& aInterface)
452
0
{
453
0
  if (!mSocket) {
454
0
    NS_WARNING("multicast socket is closed");
455
0
    FireInternalError(__LINE__);
456
0
    return IPC_OK();
457
0
  }
458
0
459
0
  nsresult rv = mSocket->JoinMulticast(aMulticastAddress, aInterface);
460
0
461
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
462
0
    FireInternalError(__LINE__);
463
0
  }
464
0
465
0
  return IPC_OK();
466
0
}
467
468
mozilla::ipc::IPCResult
469
UDPSocketParent::RecvLeaveMulticast(const nsCString& aMulticastAddress,
470
                                    const nsCString& aInterface)
471
0
{
472
0
  if (!mSocket) {
473
0
    NS_WARNING("multicast socket is closed");
474
0
    FireInternalError(__LINE__);
475
0
    return IPC_OK();
476
0
  }
477
0
478
0
  nsresult rv = mSocket->LeaveMulticast(aMulticastAddress, aInterface);
479
0
480
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
481
0
    FireInternalError(__LINE__);
482
0
  }
483
0
484
0
  return IPC_OK();
485
0
}
486
487
mozilla::ipc::IPCResult
488
UDPSocketParent::RecvClose()
489
0
{
490
0
  if (!mSocket) {
491
0
    return IPC_OK();
492
0
  }
493
0
494
0
  nsresult rv = mSocket->Close();
495
0
  mSocket = nullptr;
496
0
497
0
  mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
498
0
499
0
  return IPC_OK();
500
0
}
501
502
mozilla::ipc::IPCResult
503
UDPSocketParent::RecvRequestDelete()
504
0
{
505
0
  mozilla::Unused << Send__delete__(this);
506
0
  return IPC_OK();
507
0
}
508
509
void
510
UDPSocketParent::ActorDestroy(ActorDestroyReason why)
511
0
{
512
0
  MOZ_ASSERT(mIPCOpen);
513
0
  mIPCOpen = false;
514
0
  if (mSocket) {
515
0
    mSocket->Close();
516
0
  }
517
0
  mSocket = nullptr;
518
0
}
519
520
// nsIUDPSocketListener
521
522
NS_IMETHODIMP
523
UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
524
0
{
525
0
  // receiving packet from remote host, forward the message content to child process
526
0
  if (!mIPCOpen) {
527
0
    return NS_OK;
528
0
  }
529
0
530
0
  uint16_t port;
531
0
  nsCString ip;
532
0
  nsCOMPtr<nsINetAddr> fromAddr;
533
0
  aMessage->GetFromAddr(getter_AddRefs(fromAddr));
534
0
  fromAddr->GetPort(&port);
535
0
  fromAddr->GetAddress(ip);
536
0
537
0
  nsCString data;
538
0
  aMessage->GetData(data);
539
0
540
0
  const char* buffer = data.get();
541
0
  uint32_t len = data.Length();
542
0
  UDPSOCKET_LOG(("%s: %s:%u, length %u", __FUNCTION__, ip.get(), port, len));
543
0
544
0
  if (mFilter) {
545
0
    bool allowed;
546
0
    mozilla::net::NetAddr addr;
547
0
    fromAddr->GetNetAddr(&addr);
548
0
    nsresult rv = mFilter->FilterPacket(&addr,
549
0
                                        (const uint8_t*)buffer, len,
550
0
                                        nsISocketFilter::SF_INCOMING,
551
0
                                        &allowed);
552
0
    // Receiving unallowed data, drop.
553
0
    if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
554
0
      if (!allowed) {
555
0
        UDPSOCKET_LOG(("%s: not allowed", __FUNCTION__));
556
0
      }
557
0
      return NS_OK;
558
0
    }
559
0
  }
560
0
561
0
  FallibleTArray<uint8_t> fallibleArray;
562
0
  if (!fallibleArray.InsertElementsAt(0, buffer, len, fallible)) {
563
0
    FireInternalError(__LINE__);
564
0
    return NS_ERROR_OUT_OF_MEMORY;
565
0
  }
566
0
  InfallibleTArray<uint8_t> infallibleArray;
567
0
  infallibleArray.SwapElements(fallibleArray);
568
0
569
0
  // compose callback
570
0
  mozilla::Unused << SendCallbackReceivedData(UDPAddressInfo(ip, port), infallibleArray);
571
0
572
0
  return NS_OK;
573
0
}
574
575
NS_IMETHODIMP
576
UDPSocketParent::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
577
0
{
578
0
  // underlying socket is dead, send state update to child process
579
0
  if (mIPCOpen) {
580
0
    mozilla::Unused << SendCallbackClosed();
581
0
  }
582
0
  return NS_OK;
583
0
}
584
585
void
586
UDPSocketParent::FireInternalError(uint32_t aLineNo)
587
0
{
588
0
  if (!mIPCOpen) {
589
0
    return;
590
0
  }
591
0
592
0
  mozilla::Unused << SendCallbackError(NS_LITERAL_CSTRING("Internal error"),
593
0
                                       NS_LITERAL_CSTRING(__FILE__), aLineNo);
594
0
}
595
596
void
597
UDPSocketParent::SendInternalError(nsIEventTarget *aThread,
598
                                   uint32_t aLineNo)
599
0
{
600
0
  UDPSOCKET_LOG(("SendInternalError: %u", aLineNo));
601
0
  Unused <<
602
0
    NS_WARN_IF(NS_FAILED(aThread->Dispatch(WrapRunnable(
603
0
                                             RefPtr<UDPSocketParent>(this),
604
0
                                             &UDPSocketParent::FireInternalError,
605
0
                                             aLineNo),
606
0
                                           NS_DISPATCH_NORMAL)));
607
0
}
608
609
} // namespace dom
610
} // namespace mozilla