tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Http3ConnectUDPStream.cpp (10630B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 // HttpLog.h should generally be included first
      7 #include "HttpLog.h"
      8 
      9 #include "Http3ConnectUDPStream.h"
     10 #include "HttpConnectionUDP.h"
     11 #include "Http3Session.h"
     12 #include "mozilla/net/UriTemplate.h"
     13 #include "nsIPipe.h"
     14 #include "nsIOService.h"
     15 #include "nsHttpHandler.h"
     16 #include "nsNetAddr.h"
     17 #include "nsProxyInfo.h"
     18 
     19 namespace mozilla::net {
     20 
     21 NS_IMPL_ISUPPORTS(Http3ConnectUDPStream, nsIUDPSocket)
     22 
     23 Http3ConnectUDPStream::Http3ConnectUDPStream(nsAHttpTransaction* aTrans,
     24                                             Http3SessionBase* aSession,
     25                                             nsIEventTarget* aTarget)
     26    : Http3TunnelStreamBase(aTrans, aSession), mTarget(aTarget) {
     27  LOG(("Http3ConnectUDPStream ctor %p", this));
     28 }
     29 
     30 Http3ConnectUDPStream::~Http3ConnectUDPStream() {
     31  LOG(("Http3ConnectUDPStream dtor %p", this));
     32 }
     33 
     34 already_AddRefed<HttpConnectionUDP> Http3ConnectUDPStream::CreateUDPConnection(
     35    nsIInterfaceRequestor* aCallbacks) {
     36  LOG(("Http3ConnectUDPStream::CreateUDPConnection %p", this));
     37  RefPtr<HttpConnectionUDP> conn = new HttpConnectionUDP();
     38  NetAddr peerAddr;
     39  peerAddr.InitFromString("127.0.0.1"_ns);
     40  nsresult rv =
     41      conn->InitWithSocket(mTransaction->ConnectionInfo(), this, peerAddr,
     42                           aCallbacks, mTransaction->Caps());
     43  if (NS_FAILED(rv)) {
     44    return nullptr;
     45  }
     46 
     47  return conn.forget();
     48 }
     49 
     50 void Http3ConnectUDPStream::Close(nsresult aResult) {
     51  LOG(("Http3ConnectUDPStream::Close %p aResult=%x", this,
     52       static_cast<uint32_t>(aResult)));
     53  if (mSyncListener) {
     54    (void)mSyncListener->OnStopListening(this, aResult);
     55  }
     56  mRecvState = RECV_DONE;
     57  mSendState = SEND_DONE;
     58  if (mTransaction) {
     59    mTransaction->Close(aResult);
     60    mTransaction = nullptr;
     61  }
     62 
     63  mSession = nullptr;
     64 }
     65 
     66 void Http3ConnectUDPStream::OnDatagramReceived(nsTArray<uint8_t>&& aData) {
     67  LOG(("Http3ConnectUDPStream::OnDatagramReceived %p", this));
     68 
     69  mByteReadCount += aData.Length();
     70  mReceivedData.Push(MakeUnique<UDPPayload>(std::move(aData)));
     71  if (mSyncListener) {
     72    mSyncListener->OnPacketReceived(this);
     73  }
     74 }
     75 
     76 bool Http3ConnectUDPStream::OnActivated() {
     77  LOG(("Http3ConnectUDPStream::OnActivated %p", this));
     78  mSession->FinishTunnelSetup(mTransaction);
     79  return false;
     80 }
     81 
     82 nsresult Http3ConnectUDPStream::OnProcessDatagram() {
     83  LOG(("Http3ConnectUDPStream::OnProcessDatagram %p", this));
     84 
     85  while (!mOutputData.IsEmpty()) {
     86    nsTArray<uint8_t> data = mOutputData.Pop()->TakeData();
     87    mSession->SendHTTPDatagram(mStreamId, data, mTrackingId++);
     88  }
     89  return NS_OK;
     90 }
     91 
     92 nsresult Http3ConnectUDPStream::TryActivating() {
     93  nsProxyInfo* info = mTransaction->ConnectionInfo()->ProxyInfo();
     94  if (!info) {
     95    return NS_ERROR_UNEXPECTED;
     96  }
     97 
     98  RefPtr<UriTemplateWrapper> builder;
     99  UriTemplateWrapper::Init(info->MasqueTemplate(), getter_AddRefs(builder));
    100  if (!builder) {
    101    return NS_ERROR_UNEXPECTED;
    102  }
    103 
    104  bool useRoutedHost =
    105      !mTransaction->ConnectionInfo()->GetRoutedHost().IsEmpty();
    106  nsresult rv = builder->Set(
    107      "target_host"_ns, useRoutedHost
    108                            ? mTransaction->ConnectionInfo()->GetRoutedHost()
    109                            : mTransaction->ConnectionInfo()->GetOrigin());
    110  if (NS_FAILED(rv)) {
    111    return rv;
    112  }
    113  rv = builder->Set("target_port"_ns,
    114                    useRoutedHost
    115                        ? mTransaction->ConnectionInfo()->RoutedPort()
    116                        : mTransaction->ConnectionInfo()->OriginPort());
    117  if (NS_FAILED(rv)) {
    118    return rv;
    119  }
    120 
    121  nsCString pathQuery;
    122  builder->Build(&pathQuery);
    123  LOG(("Http3ConnectUDPStream::TryActivating [host=%s pathQuery=%s]",
    124       info->Host().get(), pathQuery.get()));
    125  return mSession->TryActivating(""_ns, ""_ns, info->Host(), pathQuery,
    126                                 mFlatHttpRequestHeaders, &mStreamId, this);
    127 }
    128 
    129 void Http3ConnectUDPStream::OnSocketReady(PRFileDesc* fd, int16_t outFlags) {}
    130 
    131 void Http3ConnectUDPStream::OnSocketDetached(PRFileDesc* fd) {}
    132 
    133 void Http3ConnectUDPStream::IsLocal(bool* aIsLocal) {}
    134 
    135 nsresult Http3ConnectUDPStream::GetRemoteAddr(NetAddr* addr) { return NS_OK; }
    136 
    137 NS_IMETHODIMP Http3ConnectUDPStream::Init(int32_t aPort, bool aLoopbackOnly,
    138                                          nsIPrincipal* aPrincipal,
    139                                          bool aAddressReuse, uint8_t _argc) {
    140  return NS_OK;
    141 }
    142 
    143 NS_IMETHODIMP Http3ConnectUDPStream::Init2(const nsACString& aAddr,
    144                                           int32_t aPort,
    145                                           nsIPrincipal* aPrincipal,
    146                                           bool aAddressReuse, uint8_t _argc) {
    147  return NS_ERROR_NOT_IMPLEMENTED;
    148 }
    149 
    150 NS_IMETHODIMP Http3ConnectUDPStream::InitWithAddress(
    151    const mozilla::net::NetAddr* aAddr, nsIPrincipal* aPrincipal,
    152    bool aAddressReuse, uint8_t _argc) {
    153  return NS_OK;
    154 }
    155 
    156 NS_IMETHODIMP Http3ConnectUDPStream::Close() {
    157  Close(NS_ERROR_ABORT);
    158  return NS_OK;
    159 }
    160 
    161 NS_IMETHODIMP Http3ConnectUDPStream::AsyncListen(
    162    nsIUDPSocketListener* aListener) {
    163  return NS_ERROR_NOT_IMPLEMENTED;
    164 }
    165 
    166 NS_IMETHODIMP Http3ConnectUDPStream::SyncListen(
    167    nsIUDPSocketSyncListener* aListener) {
    168  mSyncListener = aListener;
    169  return NS_OK;
    170 }
    171 
    172 NS_IMETHODIMP Http3ConnectUDPStream::Connect(
    173    const mozilla::net::NetAddr* aAddr) {
    174  return NS_ERROR_NOT_IMPLEMENTED;
    175 }
    176 
    177 NS_IMETHODIMP Http3ConnectUDPStream::GetLocalAddr(nsINetAddr** aLocalAddr) {
    178  NetAddr addr;
    179  addr.InitFromString("0.0.0.0"_ns);
    180  nsCOMPtr<nsINetAddr> result = new nsNetAddr(&addr);
    181  result.forget(aLocalAddr);
    182  return NS_OK;
    183 }
    184 
    185 NS_IMETHODIMP Http3ConnectUDPStream::GetPort(int32_t* aPort) { return NS_OK; }
    186 
    187 NS_IMETHODIMP Http3ConnectUDPStream::GetAddress(
    188    mozilla::net::NetAddr* _retval) {
    189  return NS_ERROR_NOT_IMPLEMENTED;
    190 }
    191 
    192 NS_IMETHODIMP Http3ConnectUDPStream::Send(const nsACString& host, uint16_t port,
    193                                          const nsTArray<uint8_t>& data,
    194                                          uint32_t* _retval) {
    195  return NS_ERROR_NOT_IMPLEMENTED;
    196 }
    197 
    198 NS_IMETHODIMP Http3ConnectUDPStream::SendWithAddr(nsINetAddr* addr,
    199                                                  const nsTArray<uint8_t>& data,
    200                                                  uint32_t* _retval) {
    201  return NS_ERROR_NOT_IMPLEMENTED;
    202 }
    203 
    204 NS_IMETHODIMP Http3ConnectUDPStream::RecvWithAddr(mozilla::net::NetAddr* addr,
    205                                                  nsTArray<uint8_t>& data) {
    206  if (mReceivedData.IsEmpty()) {
    207    return NS_OK;
    208  }
    209 
    210  // TODO: should we use a real IP address here?
    211  addr->InitFromString("127.0.0.1"_ns);
    212  nsTArray<uint8_t> res = mReceivedData.Pop()->TakeData();
    213  data.AppendElements(std::move(res));
    214  return NS_OK;
    215 }
    216 
    217 NS_IMETHODIMP Http3ConnectUDPStream::SendWithAddress(
    218    const mozilla::net::NetAddr* addr, const uint8_t* data, uint32_t length,
    219    uint32_t* _retval) {
    220  LOG(("Http3ConnectUDPStream::SendWithAddress %p mSendState=%d length=%d",
    221       this, static_cast<uint32_t>(mSendState), length));
    222  if (mSendState != PROCESSING_DATAGRAM) {
    223    return NS_ERROR_NOT_AVAILABLE;
    224  }
    225 
    226  nsTArray<uint8_t> datagram;
    227  datagram.AppendElements(data, length);
    228  mOutputData.Push(MakeUnique<UDPPayload>(std::move(datagram)));
    229  mByteWriteCount += length;
    230  mSession->StreamHasDataToWrite(this);
    231  return NS_OK;
    232 }
    233 
    234 NS_IMETHODIMP Http3ConnectUDPStream::SendBinaryStream(const nsACString& host,
    235                                                      uint16_t port,
    236                                                      nsIInputStream* stream) {
    237  return NS_ERROR_NOT_IMPLEMENTED;
    238 }
    239 
    240 NS_IMETHODIMP Http3ConnectUDPStream::SendBinaryStreamWithAddress(
    241    const mozilla::net::NetAddr* addr, nsIInputStream* stream) {
    242  return NS_ERROR_NOT_IMPLEMENTED;
    243 }
    244 
    245 NS_IMETHODIMP Http3ConnectUDPStream::JoinMulticast(const nsACString& addr,
    246                                                   const nsACString& iface) {
    247  return NS_ERROR_NOT_IMPLEMENTED;
    248 }
    249 
    250 NS_IMETHODIMP Http3ConnectUDPStream::JoinMulticastAddr(
    251    const mozilla::net::NetAddr addr, const mozilla::net::NetAddr* iface) {
    252  return NS_ERROR_NOT_IMPLEMENTED;
    253 }
    254 
    255 NS_IMETHODIMP Http3ConnectUDPStream::LeaveMulticast(const nsACString& addr,
    256                                                    const nsACString& iface) {
    257  return NS_ERROR_NOT_IMPLEMENTED;
    258 }
    259 
    260 NS_IMETHODIMP Http3ConnectUDPStream::LeaveMulticastAddr(
    261    const mozilla::net::NetAddr addr, const mozilla::net::NetAddr* iface) {
    262  return NS_ERROR_NOT_IMPLEMENTED;
    263 }
    264 
    265 int64_t Http3ConnectUDPStream::GetFileDescriptor() { return -1; }
    266 
    267 void Http3ConnectUDPStream::EnableWritePoll() {}
    268 
    269 bool Http3ConnectUDPStream::IsSocketClosed() { return mSendState == SEND_DONE; }
    270 
    271 void Http3ConnectUDPStream::AddOutputBytes(uint32_t aBytes) {}
    272 
    273 void Http3ConnectUDPStream::AddInputBytes(uint32_t aBytes) {}
    274 
    275 NS_IMETHODIMP Http3ConnectUDPStream::GetMulticastLoopback(
    276    bool* aMulticastLoopback) {
    277  return NS_ERROR_NOT_IMPLEMENTED;
    278 }
    279 
    280 NS_IMETHODIMP Http3ConnectUDPStream::SetMulticastLoopback(
    281    bool aMulticastLoopback) {
    282  return NS_ERROR_NOT_IMPLEMENTED;
    283 }
    284 
    285 NS_IMETHODIMP Http3ConnectUDPStream::GetMulticastInterface(
    286    nsACString& aMulticastInterface) {
    287  return NS_ERROR_NOT_IMPLEMENTED;
    288 }
    289 
    290 NS_IMETHODIMP Http3ConnectUDPStream::SetMulticastInterface(
    291    const nsACString& aMulticastInterface) {
    292  return NS_ERROR_NOT_IMPLEMENTED;
    293 }
    294 
    295 NS_IMETHODIMP Http3ConnectUDPStream::GetMulticastInterfaceAddr(
    296    mozilla::net::NetAddr* aMulticastInterfaceAddr) {
    297  return NS_ERROR_NOT_IMPLEMENTED;
    298 }
    299 
    300 NS_IMETHODIMP Http3ConnectUDPStream::SetMulticastInterfaceAddr(
    301    mozilla::net::NetAddr aMulticastInterfaceAddr) {
    302  return NS_ERROR_NOT_IMPLEMENTED;
    303 }
    304 
    305 NS_IMETHODIMP Http3ConnectUDPStream::GetRecvBufferSize(
    306    int32_t* aRecvBufferSize) {
    307  return NS_ERROR_NOT_IMPLEMENTED;
    308 }
    309 
    310 NS_IMETHODIMP Http3ConnectUDPStream::SetRecvBufferSize(
    311    int32_t aRecvBufferSize) {
    312  return NS_OK;
    313 }
    314 
    315 NS_IMETHODIMP Http3ConnectUDPStream::GetSendBufferSize(
    316    int32_t* aSendBufferSize) {
    317  return NS_ERROR_NOT_IMPLEMENTED;
    318 }
    319 
    320 NS_IMETHODIMP Http3ConnectUDPStream::SetSendBufferSize(
    321    int32_t aSendBufferSize) {
    322  return NS_ERROR_NOT_IMPLEMENTED;
    323 }
    324 
    325 NS_IMETHODIMP Http3ConnectUDPStream::GetDontFragment(bool* aDontFragment) {
    326  return NS_ERROR_NOT_IMPLEMENTED;
    327 }
    328 
    329 NS_IMETHODIMP Http3ConnectUDPStream::SetDontFragment(bool aDontFragment) {
    330  return NS_OK;
    331 }
    332 
    333 }  // namespace mozilla::net