dom/network/src/UDPSocketParent.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     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/net/DNS.h"
    15 namespace mozilla {
    16 namespace dom {
    18 static void
    19 FireInternalError(mozilla::net::PUDPSocketParent *aActor, uint32_t aLineNo)
    20 {
    21   mozilla::unused <<
    22       aActor->SendCallback(NS_LITERAL_CSTRING("onerror"),
    23                           UDPError(NS_LITERAL_CSTRING("Internal error"),
    24                                    NS_LITERAL_CSTRING(__FILE__), aLineNo, 0),
    25                           NS_LITERAL_CSTRING("connecting"));
    26 }
    28 static nsresult
    29 ConvertNetAddrToString(mozilla::net::NetAddr &netAddr, nsACString *address, uint16_t *port)
    30 {
    31   NS_ENSURE_ARG_POINTER(address);
    32   NS_ENSURE_ARG_POINTER(port);
    34   *port = 0;
    35   uint32_t bufSize = 0;
    37   switch(netAddr.raw.family) {
    38   case AF_INET:
    39     *port = PR_ntohs(netAddr.inet.port);
    40     bufSize = mozilla::net::kIPv4CStrBufSize;
    41     break;
    42   case AF_INET6:
    43     *port = PR_ntohs(netAddr.inet6.port);
    44     bufSize = mozilla::net::kIPv6CStrBufSize;
    45     break;
    46   default:
    47     //impossible
    48     MOZ_ASSERT(false, "Unexpected address family");
    49     return NS_ERROR_INVALID_ARG;
    50   }
    52   address->SetCapacity(bufSize);
    53   NetAddrToString(&netAddr, address->BeginWriting(), bufSize);
    54   address->SetLength(strlen(address->BeginReading()));
    56   return NS_OK;
    57 }
    59 NS_IMPL_ISUPPORTS(UDPSocketParent, nsIUDPSocketListener)
    61 UDPSocketParent::~UDPSocketParent()
    62 {
    63 }
    65 // PUDPSocketParent methods
    67 bool
    68 UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
    69 {
    70   nsresult rv;
    71   NS_ASSERTION(mFilter, "No packet filter");
    73   nsCOMPtr<nsIUDPSocket> sock =
    74       do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
    75   if (NS_FAILED(rv)) {
    76     FireInternalError(this, __LINE__);
    77     return true;
    78   }
    80   if (aHost.IsEmpty()) {
    81     rv = sock->Init(aPort, false);
    82   } else {
    83     PRNetAddr prAddr;
    84     PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    85     PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    86     if (status != PR_SUCCESS) {
    87       FireInternalError(this, __LINE__);
    88       return true;
    89     }
    91     mozilla::net::NetAddr addr;
    92     PRNetAddrToNetAddr(&prAddr, &addr);
    93     rv = sock->InitWithAddress(&addr);
    94   }
    96   if (NS_FAILED(rv)) {
    97     FireInternalError(this, __LINE__);
    98     return true;
    99   }
   101   mSocket = sock;
   103   net::NetAddr localAddr;
   104   mSocket->GetAddress(&localAddr);
   106   uint16_t port;
   107   nsCString addr;
   108   rv = ConvertNetAddrToString(localAddr, &addr, &port);
   110   if (NS_FAILED(rv)) {
   111     FireInternalError(this, __LINE__);
   112     return true;
   113   }
   115   // register listener
   116   mSocket->AsyncListen(this);
   117   mozilla::unused <<
   118       PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"),
   119                                      UDPAddressInfo(addr, port),
   120                                      NS_LITERAL_CSTRING("connected"));
   122   return true;
   123 }
   125 bool
   126 UDPSocketParent::RecvData(const InfallibleTArray<uint8_t> &aData,
   127                           const nsCString& aRemoteAddress,
   128                           const uint16_t& aPort)
   129 {
   130   NS_ENSURE_TRUE(mSocket, true);
   131   NS_ASSERTION(mFilter, "No packet filter");
   132   // TODO, Bug 933102, filter packets that are sent with hostname.
   133   // Until then we simply throw away packets that are sent to a hostname.
   134   return true;
   136 #if 0
   137   // Enable this once we have filtering working with hostname delivery.
   138   uint32_t count;
   139   nsresult rv = mSocket->Send(aRemoteAddress,
   140                               aPort, aData.Elements(),
   141                               aData.Length(), &count);
   142   mozilla::unused <<
   143       PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onsent"),
   144                                      UDPSendResult(rv),
   145                                      NS_LITERAL_CSTRING("connected"));
   146   NS_ENSURE_SUCCESS(rv, true);
   147   NS_ENSURE_TRUE(count > 0, true);
   148   return true;
   149 #endif
   150 }
   152 bool
   153 UDPSocketParent::RecvDataWithAddress(const InfallibleTArray<uint8_t>& aData,
   154                                      const mozilla::net::NetAddr& aAddr)
   155 {
   156   NS_ENSURE_TRUE(mSocket, true);
   157   NS_ASSERTION(mFilter, "No packet filter");
   159   uint32_t count;
   160   nsresult rv;
   161   bool allowed;
   162   rv = mFilter->FilterPacket(&aAddr, aData.Elements(),
   163                              aData.Length(), nsIUDPSocketFilter::SF_OUTGOING,
   164                              &allowed);
   165   // Sending unallowed data, kill content.
   166   NS_ENSURE_SUCCESS(rv, false);
   167   NS_ENSURE_TRUE(allowed, false);
   169   rv = mSocket->SendWithAddress(&aAddr, aData.Elements(),
   170                                 aData.Length(), &count);
   171   mozilla::unused <<
   172       PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onsent"),
   173                                      UDPSendResult(rv),
   174                                      NS_LITERAL_CSTRING("connected"));
   175   NS_ENSURE_SUCCESS(rv, true);
   176   NS_ENSURE_TRUE(count > 0, true);
   177   return true;
   178 }
   180 bool
   181 UDPSocketParent::RecvClose()
   182 {
   183   NS_ENSURE_TRUE(mSocket, true);
   184   nsresult rv = mSocket->Close();
   185   mSocket = nullptr;
   186   NS_ENSURE_SUCCESS(rv, true);
   187   return true;
   188 }
   190 bool
   191 UDPSocketParent::RecvRequestDelete()
   192 {
   193   mozilla::unused << Send__delete__(this);
   194   return true;
   195 }
   197 void
   198 UDPSocketParent::ActorDestroy(ActorDestroyReason why)
   199 {
   200   MOZ_ASSERT(mIPCOpen);
   201   mIPCOpen = false;
   202   if (mSocket) {
   203     mSocket->Close();
   204   }
   205   mSocket = nullptr;
   206 }
   208 // nsIUDPSocketListener
   210 NS_IMETHODIMP
   211 UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
   212 {
   213   // receiving packet from remote host, forward the message content to child process
   214   if (!mIPCOpen) {
   215     return NS_OK;
   216   }
   217   NS_ASSERTION(mFilter, "No packet filter");
   219   uint16_t port;
   220   nsCString ip;
   221   nsCOMPtr<nsINetAddr> fromAddr;
   222   aMessage->GetFromAddr(getter_AddRefs(fromAddr));
   223   fromAddr->GetPort(&port);
   224   fromAddr->GetAddress(ip);
   226   nsCString data;
   227   aMessage->GetData(data);
   229   const char* buffer = data.get();
   230   uint32_t len = data.Length();
   232   bool allowed;
   233   mozilla::net::NetAddr addr;
   234   fromAddr->GetNetAddr(&addr);
   235   nsresult rv = mFilter->FilterPacket(&addr,
   236                                       (const uint8_t*)buffer, len,
   237                                       nsIUDPSocketFilter::SF_INCOMING,
   238                                       &allowed);
   239   // Receiving unallowed data, drop.
   240   NS_ENSURE_SUCCESS(rv, NS_OK);
   241   NS_ENSURE_TRUE(allowed, NS_OK);
   243   FallibleTArray<uint8_t> fallibleArray;
   244   if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
   245     FireInternalError(this, __LINE__);
   246     return NS_ERROR_OUT_OF_MEMORY;
   247   }
   248   InfallibleTArray<uint8_t> infallibleArray;
   249   infallibleArray.SwapElements(fallibleArray);
   251   // compose callback
   252   mozilla::unused <<
   253       PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("ondata"),
   254                                      UDPMessage(ip, port, infallibleArray),
   255                                      NS_LITERAL_CSTRING("connected"));
   257   return NS_OK;
   258 }
   260 NS_IMETHODIMP
   261 UDPSocketParent::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
   262 {
   263   // underlying socket is dead, send state update to child process
   264   if (mIPCOpen) {
   265     mozilla::unused <<
   266         PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onclose"),
   267                                        mozilla::void_t(),
   268                                        NS_LITERAL_CSTRING("closed"));
   269   }
   270   return NS_OK;
   271 }
   273 } // namespace dom
   274 } // namespace mozilla

mercurial