TLSTransportLayer.cpp (27843B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=4 sw=2 et cindent: */ 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 // HttpLog.h should generally be included first 8 #include "HttpLog.h" 9 10 #include "Http2StreamTunnel.h" 11 #include "TLSTransportLayer.h" 12 #include "nsISocketProvider.h" 13 #include "nsITLSSocketControl.h" 14 #include "nsQueryObject.h" 15 #include "nsSocketProviderService.h" 16 #include "nsSocketTransport2.h" 17 18 namespace mozilla::net { 19 20 //----------------------------------------------------------------------------- 21 // TLSTransportLayerInputStream impl 22 //----------------------------------------------------------------------------- 23 24 NS_IMPL_QUERY_INTERFACE(TLSTransportLayer::InputStreamWrapper, nsIInputStream, 25 nsIAsyncInputStream) 26 27 NS_IMETHODIMP_(MozExternalRefCountType) 28 TLSTransportLayer::InputStreamWrapper::AddRef() { return mTransport->AddRef(); } 29 30 NS_IMETHODIMP_(MozExternalRefCountType) 31 TLSTransportLayer::InputStreamWrapper::Release() { 32 return mTransport->Release(); 33 } 34 35 TLSTransportLayer::InputStreamWrapper::InputStreamWrapper( 36 nsIAsyncInputStream* aInputStream, TLSTransportLayer* aTransport) 37 : mSocketIn(aInputStream), mTransport(aTransport) {} 38 39 NS_IMETHODIMP 40 TLSTransportLayer::InputStreamWrapper::Close() { 41 LOG(("TLSTransportLayer::InputStreamWrapper::Close [this=%p]\n", this)); 42 return mSocketIn->Close(); 43 } 44 45 NS_IMETHODIMP TLSTransportLayer::InputStreamWrapper::Available( 46 uint64_t* avail) { 47 LOG(("TLSTransportLayer::InputStreamWrapper::Available [this=%p]\n", this)); 48 return mSocketIn->Available(avail); 49 } 50 51 NS_IMETHODIMP TLSTransportLayer::InputStreamWrapper::StreamStatus() { 52 LOG(("TLSTransportLayer::InputStreamWrapper::StreamStatus [this=%p]\n", 53 this)); 54 return mSocketIn->StreamStatus(); 55 } 56 57 nsresult TLSTransportLayer::InputStreamWrapper::ReadDirectly( 58 char* buf, uint32_t count, uint32_t* countRead) { 59 LOG(("TLSTransportLayer::InputStreamWrapper::ReadDirectly [this=%p]\n", 60 this)); 61 return mSocketIn->Read(buf, count, countRead); 62 } 63 64 NS_IMETHODIMP 65 TLSTransportLayer::InputStreamWrapper::Read(char* buf, uint32_t count, 66 uint32_t* countRead) { 67 LOG(("TLSTransportLayer::InputStreamWrapper::Read [this=%p]\n", this)); 68 69 *countRead = 0; 70 71 if (NS_FAILED(mStatus)) { 72 return (mStatus == NS_BASE_STREAM_CLOSED) ? NS_OK : mStatus; 73 } 74 75 int32_t bytesRead = PR_Read(mTransport->mFD, buf, count); 76 if (bytesRead > 0) { 77 *countRead = bytesRead; 78 } else if (bytesRead < 0) { 79 PRErrorCode code = PR_GetError(); 80 if (code == PR_WOULD_BLOCK_ERROR) { 81 LOG(( 82 "TLSTransportLayer::InputStreamWrapper::Read %p PR_Read would block ", 83 this)); 84 return NS_BASE_STREAM_WOULD_BLOCK; 85 } 86 // If reading from the socket succeeded (NS_SUCCEEDED(mStatus)), 87 // but the nss layer encountered an error remember the error. 88 if (NS_SUCCEEDED(mStatus)) { 89 mStatus = mTransport->mInputStatus; 90 LOG(( 91 "TLSTransportLayer::InputStreamWrapper::Read %p socket error %" PRIx32 92 ".\n", 93 this, static_cast<uint32_t>(mStatus))); 94 } 95 } 96 97 if (NS_SUCCEEDED(mStatus) && !bytesRead) { 98 LOG( 99 ("TLSTransportLayer::InputStreamWrapper::Read %p " 100 "Second layer of TLS stripping results in STREAM_CLOSED\n", 101 this)); 102 mStatus = NS_BASE_STREAM_CLOSED; 103 } 104 105 LOG(("TLSTransportLayer::InputStreamWrapper::Read %p rv=%" PRIx32 106 " didread=%d " 107 "2 layers of ssl stripped to plaintext\n", 108 this, static_cast<uint32_t>(mStatus), bytesRead)); 109 return mStatus; 110 } 111 112 NS_IMETHODIMP 113 TLSTransportLayer::InputStreamWrapper::ReadSegments(nsWriteSegmentFun writer, 114 void* closure, 115 uint32_t count, 116 uint32_t* countRead) { 117 LOG(("TLSTransportLayer::InputStreamWrapper::ReadSegments [this=%p]\n", 118 this)); 119 return mSocketIn->ReadSegments(writer, closure, count, countRead); 120 } 121 122 NS_IMETHODIMP 123 TLSTransportLayer::InputStreamWrapper::IsNonBlocking(bool* nonblocking) { 124 return mSocketIn->IsNonBlocking(nonblocking); 125 } 126 127 NS_IMETHODIMP 128 TLSTransportLayer::InputStreamWrapper::CloseWithStatus(nsresult reason) { 129 LOG( 130 ("TLSTransportLayer::InputStreamWrapper::CloseWithStatus [this=%p " 131 "reason=%" PRIx32 "]\n", 132 this, static_cast<uint32_t>(reason))); 133 mStatus = reason; 134 return mSocketIn->CloseWithStatus(reason); 135 } 136 137 NS_IMETHODIMP 138 TLSTransportLayer::InputStreamWrapper::AsyncWait( 139 nsIInputStreamCallback* callback, uint32_t flags, uint32_t amount, 140 nsIEventTarget* target) { 141 LOG( 142 ("TLSTransportLayer::InputStreamWrapper::AsyncWait [this=%p, " 143 "callback=%p]\n", 144 this, callback)); 145 mTransport->mInputCallback = callback; 146 // Don't bother to call PR_POLL when |callback| is NULL. We call |AsyncWait| 147 // directly to null out the underlying callback. 148 if (!callback) { 149 return mSocketIn->AsyncWait(nullptr, 0, 0, nullptr); 150 } 151 152 PRPollDesc pd; 153 pd.fd = mTransport->mFD; 154 pd.in_flags = PR_POLL_READ | PR_POLL_EXCEPT; 155 // Only run PR_Poll on the socket thread. Also, make sure this lives at least 156 // as long as that operation. 157 auto DoPoll = [self = RefPtr{this}, pd(pd)]() mutable { 158 int32_t rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); 159 LOG(("TLSTransportLayer::InputStreamWrapper::AsyncWait rv=%d", rv)); 160 }; 161 if (OnSocketThread()) { 162 DoPoll(); 163 } else { 164 gSocketTransportService->Dispatch(NS_NewRunnableFunction( 165 "TLSTransportLayer::InputStreamWrapper::AsyncWait", DoPoll)); 166 } 167 return NS_OK; 168 } 169 170 //----------------------------------------------------------------------------- 171 // TLSTransportLayerOutputStream impl 172 //----------------------------------------------------------------------------- 173 174 NS_IMPL_QUERY_INTERFACE(TLSTransportLayer::OutputStreamWrapper, nsIOutputStream, 175 nsIAsyncOutputStream) 176 177 NS_IMETHODIMP_(MozExternalRefCountType) 178 TLSTransportLayer::OutputStreamWrapper::AddRef() { 179 return mTransport->AddRef(); 180 } 181 182 NS_IMETHODIMP_(MozExternalRefCountType) 183 TLSTransportLayer::OutputStreamWrapper::Release() { 184 return mTransport->Release(); 185 } 186 187 TLSTransportLayer::OutputStreamWrapper::OutputStreamWrapper( 188 nsIAsyncOutputStream* aOutputStream, TLSTransportLayer* aTransport) 189 : mSocketOut(aOutputStream), mTransport(aTransport) {} 190 191 NS_IMETHODIMP 192 TLSTransportLayer::OutputStreamWrapper::Close() { 193 LOG(("TLSTransportLayer::OutputStreamWrapper::Close [this=%p]\n", this)); 194 return mSocketOut->Close(); 195 } 196 197 NS_IMETHODIMP 198 TLSTransportLayer::OutputStreamWrapper::Flush() { 199 LOG(("TLSTransportLayerOutputStream::Flush [this=%p]\n", this)); 200 return mSocketOut->Flush(); 201 } 202 203 NS_IMETHODIMP 204 TLSTransportLayer::OutputStreamWrapper::StreamStatus() { 205 LOG(("TLSTransportLayerOutputStream::StreamStatus [this=%p]\n", this)); 206 return mSocketOut->StreamStatus(); 207 } 208 209 nsresult TLSTransportLayer::OutputStreamWrapper::WriteDirectly( 210 const char* buf, uint32_t count, uint32_t* countWritten) { 211 LOG( 212 ("TLSTransportLayer::OutputStreamWrapper::WriteDirectly [this=%p " 213 "count=%u]\n", 214 this, count)); 215 return mSocketOut->Write(buf, count, countWritten); 216 } 217 218 NS_IMETHODIMP 219 TLSTransportLayer::OutputStreamWrapper::Write(const char* buf, uint32_t count, 220 uint32_t* countWritten) { 221 LOG(("TLSTransportLayer::OutputStreamWrapper::Write [this=%p count=%u]\n", 222 this, count)); 223 224 *countWritten = 0; 225 226 if (NS_FAILED(mStatus)) { 227 return (mStatus == NS_BASE_STREAM_CLOSED) ? NS_OK : mStatus; 228 } 229 230 int32_t written = PR_Write(mTransport->mFD, buf, count); 231 LOG(("TLSTransportLayer::OutputStreamWrapper::Write %p PRWrite(%d) = %d", 232 this, count, written)); 233 234 if (written > 0) { 235 *countWritten = written; 236 } else if (written < 0) { 237 PRErrorCode code = PR_GetError(); 238 if (code == PR_WOULD_BLOCK_ERROR) { 239 LOG( 240 ("TLSTransportLayer::OutputStreamWrapper::Write %p PRWrite would " 241 "block ", 242 this)); 243 return NS_BASE_STREAM_WOULD_BLOCK; 244 } 245 246 // Writing to the socket succeeded, but failed in nss layer. 247 if (NS_SUCCEEDED(mStatus)) { 248 mStatus = mTransport->mOutputStatus; 249 LOG( 250 ("TLSTransportLayer:::OutputStreamWrapper::Write %p socket error " 251 "%" PRIx32 " code=%d\n", 252 this, static_cast<uint32_t>(mStatus), code)); 253 } 254 } 255 256 return mStatus; 257 } 258 259 NS_IMETHODIMP 260 TLSTransportLayer::OutputStreamWrapper::WriteSegments(nsReadSegmentFun reader, 261 void* closure, 262 uint32_t count, 263 uint32_t* countRead) { 264 return mSocketOut->WriteSegments(reader, closure, count, countRead); 265 } 266 267 // static 268 nsresult TLSTransportLayer::OutputStreamWrapper::WriteFromSegments( 269 nsIInputStream* input, void* closure, const char* fromSegment, 270 uint32_t offset, uint32_t count, uint32_t* countRead) { 271 OutputStreamWrapper* self = (OutputStreamWrapper*)closure; 272 return self->Write(fromSegment, count, countRead); 273 } 274 275 NS_IMETHODIMP 276 TLSTransportLayer::OutputStreamWrapper::WriteFrom(nsIInputStream* stream, 277 uint32_t count, 278 uint32_t* countRead) { 279 return stream->ReadSegments(WriteFromSegments, this, count, countRead); 280 } 281 282 NS_IMETHODIMP 283 TLSTransportLayer::OutputStreamWrapper::IsNonBlocking(bool* nonblocking) { 284 return mSocketOut->IsNonBlocking(nonblocking); 285 } 286 287 NS_IMETHODIMP 288 TLSTransportLayer::OutputStreamWrapper::CloseWithStatus(nsresult reason) { 289 LOG(("OutputStreamWrapper::CloseWithStatus [this=%p reason=%" PRIx32 "]\n", 290 this, static_cast<uint32_t>(reason))); 291 mStatus = reason; 292 return mSocketOut->CloseWithStatus(reason); 293 } 294 295 NS_IMETHODIMP 296 TLSTransportLayer::OutputStreamWrapper::AsyncWait( 297 nsIOutputStreamCallback* callback, uint32_t flags, uint32_t amount, 298 nsIEventTarget* target) { 299 LOG( 300 ("TLSTransportLayer::OutputStreamWrapper::AsyncWait [this=%p, " 301 "mOutputCallback=%p " 302 "callback=%p]\n", 303 this, mTransport->mOutputCallback.get(), callback)); 304 mTransport->mOutputCallback = callback; 305 // Don't bother to call PR_POLL when |callback| is NULL. We call |AsyncWait| 306 // directly to null out the underlying callback. 307 if (!callback) { 308 return mSocketOut->AsyncWait(nullptr, 0, 0, nullptr); 309 } 310 311 PRPollDesc pd; 312 pd.fd = mTransport->mFD; 313 pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; 314 int32_t rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); 315 LOG(("TLSTransportLayer::OutputStreamWrapper::AsyncWait rv=%d", rv)); 316 return NS_OK; 317 } 318 319 //----------------------------------------------------------------------------- 320 // TLSTransportLayer impl 321 //----------------------------------------------------------------------------- 322 323 static PRDescIdentity sTLSTransportLayerIdentity; 324 static PRIOMethods sTLSTransportLayerMethods; 325 static PRIOMethods* sTLSTransportLayerMethodsPtr = nullptr; 326 327 bool TLSTransportLayer::DispatchRelease() { 328 if (OnSocketThread()) { 329 return false; 330 } 331 332 gSocketTransportService->Dispatch( 333 NewNonOwningRunnableMethod("net::TLSTransportLayer::Release", this, 334 &TLSTransportLayer::Release), 335 NS_DISPATCH_NORMAL); 336 337 return true; 338 } 339 340 NS_IMPL_ADDREF(TLSTransportLayer) 341 NS_IMETHODIMP_(MozExternalRefCountType) 342 TLSTransportLayer::Release() { 343 nsrefcnt count = mRefCnt - 1; 344 if (DispatchRelease()) { 345 // Redispatched to the socket thread. 346 return count; 347 } 348 349 MOZ_ASSERT(0 != mRefCnt, "dup release"); 350 count = --mRefCnt; 351 NS_LOG_RELEASE(this, count, "TLSTransportLayer"); 352 353 if (0 == count) { 354 mRefCnt = 1; 355 delete (this); 356 return 0; 357 } 358 359 return count; 360 } 361 362 NS_INTERFACE_MAP_BEGIN(TLSTransportLayer) 363 NS_INTERFACE_MAP_ENTRY(nsISocketTransport) 364 NS_INTERFACE_MAP_ENTRY(nsITransport) 365 NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback) 366 NS_INTERFACE_MAP_ENTRY(nsIOutputStreamCallback) 367 NS_INTERFACE_MAP_ENTRY_CONCRETE(TLSTransportLayer) 368 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITransport) 369 NS_INTERFACE_MAP_END 370 371 TLSTransportLayer::TLSTransportLayer(nsISocketTransport* aTransport, 372 nsIAsyncInputStream* aInputStream, 373 nsIAsyncOutputStream* aOutputStream, 374 nsIInputStreamCallback* aOwner) 375 : mSocketTransport(aTransport), 376 mSocketInWrapper(aInputStream, this), 377 mSocketOutWrapper(aOutputStream, this), 378 mOwner(aOwner) { 379 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 380 LOG(("TLSTransportLayer ctor this=[%p]", this)); 381 } 382 383 TLSTransportLayer::~TLSTransportLayer() { 384 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 385 LOG(("TLSTransportLayer dtor this=[%p]", this)); 386 if (mFD) { 387 PR_Close(mFD); 388 mFD = nullptr; 389 } 390 mTLSSocketControl = nullptr; 391 } 392 393 bool TLSTransportLayer::Init(const char* aTLSHost, int32_t aTLSPort) { 394 LOG(("TLSTransportLayer::Init this=[%p]", this)); 395 nsCOMPtr<nsISocketProvider> provider; 396 nsCOMPtr<nsISocketProviderService> spserv = 397 nsSocketProviderService::GetOrCreate(); 398 if (!spserv) { 399 return false; 400 } 401 402 spserv->GetSocketProvider("ssl", getter_AddRefs(provider)); 403 if (!provider) { 404 return false; 405 } 406 407 // Install an NSPR layer to handle getpeername() with a failure. This is kind 408 // of silly, but the default one used by the pipe asserts when called and the 409 // nss code calls it to see if we are connected to a real socket or not. 410 if (!sTLSTransportLayerMethodsPtr) { 411 // one time initialization 412 sTLSTransportLayerIdentity = PR_GetUniqueIdentity("TLSTransportLayer"); 413 sTLSTransportLayerMethods = *PR_GetDefaultIOMethods(); 414 sTLSTransportLayerMethods.getpeername = GetPeerName; 415 sTLSTransportLayerMethods.getsocketoption = GetSocketOption; 416 sTLSTransportLayerMethods.setsocketoption = SetSocketOption; 417 sTLSTransportLayerMethods.read = Read; 418 sTLSTransportLayerMethods.write = Write; 419 sTLSTransportLayerMethods.send = Send; 420 sTLSTransportLayerMethods.recv = Recv; 421 sTLSTransportLayerMethods.close = Close; 422 sTLSTransportLayerMethods.poll = Poll; 423 sTLSTransportLayerMethodsPtr = &sTLSTransportLayerMethods; 424 } 425 426 mFD = PR_CreateIOLayerStub(sTLSTransportLayerIdentity, 427 &sTLSTransportLayerMethods); 428 if (!mFD) { 429 return false; 430 } 431 432 mFD->secret = reinterpret_cast<PRFilePrivate*>(this); 433 434 return NS_SUCCEEDED(provider->AddToSocket( 435 PR_AF_INET, aTLSHost, aTLSPort, nullptr, OriginAttributes(), 0, 0, mFD, 436 getter_AddRefs(mTLSSocketControl))); 437 } 438 439 NS_IMETHODIMP 440 TLSTransportLayer::OnInputStreamReady(nsIAsyncInputStream* in) { 441 nsCOMPtr<nsIInputStreamCallback> callback = std::move(mInputCallback); 442 if (callback) { 443 return callback->OnInputStreamReady(&mSocketInWrapper); 444 } 445 return NS_OK; 446 } 447 448 NS_IMETHODIMP 449 TLSTransportLayer::OnOutputStreamReady(nsIAsyncOutputStream* out) { 450 nsCOMPtr<nsIOutputStreamCallback> callback = std::move(mOutputCallback); 451 nsresult rv = NS_OK; 452 if (callback) { 453 rv = callback->OnOutputStreamReady(&mSocketOutWrapper); 454 455 RefPtr<OutputStreamTunnel> tunnel = do_QueryObject(out); 456 if (tunnel) { 457 tunnel->MaybeSetRequestDone(callback); 458 } 459 } 460 return rv; 461 } 462 463 NS_IMETHODIMP 464 TLSTransportLayer::SetKeepaliveEnabled(bool aKeepaliveEnabled) { 465 if (!mSocketTransport) { 466 return NS_ERROR_FAILURE; 467 } 468 return mSocketTransport->SetKeepaliveEnabled(aKeepaliveEnabled); 469 } 470 471 NS_IMETHODIMP 472 TLSTransportLayer::SetKeepaliveVals(int32_t keepaliveIdleTime, 473 int32_t keepaliveRetryInterval) { 474 if (!mSocketTransport) { 475 return NS_ERROR_FAILURE; 476 } 477 return mSocketTransport->SetKeepaliveVals(keepaliveIdleTime, 478 keepaliveRetryInterval); 479 } 480 481 NS_IMETHODIMP 482 TLSTransportLayer::GetSecurityCallbacks( 483 nsIInterfaceRequestor** aSecurityCallbacks) { 484 if (!mSocketTransport) { 485 return NS_ERROR_FAILURE; 486 } 487 return mSocketTransport->GetSecurityCallbacks(aSecurityCallbacks); 488 } 489 490 NS_IMETHODIMP 491 TLSTransportLayer::SetSecurityCallbacks( 492 nsIInterfaceRequestor* aSecurityCallbacks) { 493 if (!mSocketTransport) { 494 return NS_ERROR_FAILURE; 495 } 496 497 return mSocketTransport->SetSecurityCallbacks(aSecurityCallbacks); 498 } 499 500 NS_IMETHODIMP 501 TLSTransportLayer::OpenInputStream(uint32_t aFlags, uint32_t aSegmentSize, 502 uint32_t aSegmentCount, 503 nsIInputStream** _retval) { 504 return NS_ERROR_NOT_IMPLEMENTED; 505 } 506 507 NS_IMETHODIMP 508 TLSTransportLayer::OpenOutputStream(uint32_t aFlags, uint32_t aSegmentSize, 509 uint32_t aSegmentCount, 510 nsIOutputStream** _retval) { 511 return NS_ERROR_NOT_IMPLEMENTED; 512 } 513 514 NS_IMETHODIMP 515 TLSTransportLayer::Close(nsresult aReason) { 516 LOG(("TLSTransportLayer::Close [this=%p reason=%" PRIx32 "]\n", this, 517 static_cast<uint32_t>(aReason))); 518 519 mInputCallback = nullptr; 520 mOutputCallback = nullptr; 521 if (mSocketTransport) { 522 mSocketTransport->Close(aReason); 523 mSocketTransport = nullptr; 524 } 525 mSocketInWrapper.AsyncWait(nullptr, 0, 0, nullptr); 526 mSocketInWrapper.CloseWithStatus(aReason); 527 mSocketOutWrapper.AsyncWait(nullptr, 0, 0, nullptr); 528 mSocketOutWrapper.CloseWithStatus(aReason); 529 530 if (mOwner) { 531 RefPtr<TLSTransportLayer> self = this; 532 (void)NS_DispatchToCurrentThread(NS_NewRunnableFunction( 533 "TLSTransportLayer::Close", [self{std::move(self)}]() { 534 nsCOMPtr<nsIInputStreamCallback> inputCallback = 535 std::move(self->mOwner); 536 if (inputCallback) { 537 // This is hack. We need to make 538 // nsHttpConnection::OnInputStreamReady be called, so 539 // nsHttpConnection::CloseTransaction can be called to release the 540 // transaction. 541 (void)inputCallback->OnInputStreamReady(&self->mSocketInWrapper); 542 } 543 })); 544 } 545 546 return NS_OK; 547 } 548 549 NS_IMETHODIMP 550 TLSTransportLayer::SetEventSink(nsITransportEventSink* aSink, 551 nsIEventTarget* aEventTarget) { 552 if (!mSocketTransport) { 553 return NS_ERROR_FAILURE; 554 } 555 return mSocketTransport->SetEventSink(aSink, aEventTarget); 556 } 557 558 NS_IMETHODIMP 559 TLSTransportLayer::Bind(NetAddr* aLocalAddr) { 560 if (!mSocketTransport) { 561 return NS_ERROR_FAILURE; 562 } 563 return mSocketTransport->Bind(aLocalAddr); 564 } 565 566 NS_IMETHODIMP 567 TLSTransportLayer::GetEchConfigUsed(bool* aEchConfigUsed) { 568 if (!mSocketTransport) { 569 return NS_ERROR_FAILURE; 570 } 571 return mSocketTransport->GetEchConfigUsed(aEchConfigUsed); 572 } 573 574 NS_IMETHODIMP 575 TLSTransportLayer::SetEchConfig(const nsACString& aEchConfig) { 576 if (!mSocketTransport) { 577 return NS_ERROR_FAILURE; 578 } 579 return mSocketTransport->SetEchConfig(aEchConfig); 580 } 581 582 NS_IMETHODIMP 583 TLSTransportLayer::ResolvedByTRR(bool* aResolvedByTRR) { 584 if (!mSocketTransport) { 585 return NS_ERROR_FAILURE; 586 } 587 return mSocketTransport->ResolvedByTRR(aResolvedByTRR); 588 } 589 590 NS_IMETHODIMP TLSTransportLayer::GetEffectiveTRRMode( 591 nsIRequest::TRRMode* aEffectiveTRRMode) { 592 if (!mSocketTransport) { 593 return NS_ERROR_FAILURE; 594 } 595 return mSocketTransport->GetEffectiveTRRMode(aEffectiveTRRMode); 596 } 597 598 NS_IMETHODIMP TLSTransportLayer::GetTrrSkipReason( 599 nsITRRSkipReason::value* aTrrSkipReason) { 600 if (!mSocketTransport) { 601 return NS_ERROR_FAILURE; 602 } 603 return mSocketTransport->GetTrrSkipReason(aTrrSkipReason); 604 } 605 606 #define FWD_TS_PTR(fx, ts) \ 607 NS_IMETHODIMP \ 608 TLSTransportLayer::fx(ts* arg) { \ 609 if (!mSocketTransport) return NS_ERROR_FAILURE; \ 610 return mSocketTransport->fx(arg); \ 611 } 612 613 #define FWD_TS_ADDREF(fx, ts) \ 614 NS_IMETHODIMP \ 615 TLSTransportLayer::fx(ts** arg) { \ 616 if (!mSocketTransport) return NS_ERROR_FAILURE; \ 617 return mSocketTransport->fx(arg); \ 618 } 619 620 #define FWD_TS(fx, ts) \ 621 NS_IMETHODIMP \ 622 TLSTransportLayer::fx(ts arg) { \ 623 if (!mSocketTransport) return NS_ERROR_FAILURE; \ 624 return mSocketTransport->fx(arg); \ 625 } 626 627 FWD_TS_PTR(GetKeepaliveEnabled, bool); 628 FWD_TS_PTR(GetSendBufferSize, uint32_t); 629 FWD_TS(SetSendBufferSize, uint32_t); 630 FWD_TS_PTR(GetPort, int32_t); 631 FWD_TS_PTR(GetPeerAddr, mozilla::net::NetAddr); 632 FWD_TS_PTR(GetSelfAddr, mozilla::net::NetAddr); 633 FWD_TS_ADDREF(GetScriptablePeerAddr, nsINetAddr); 634 FWD_TS_ADDREF(GetScriptableSelfAddr, nsINetAddr); 635 FWD_TS_PTR(IsAlive, bool); 636 FWD_TS_PTR(GetConnectionFlags, uint32_t); 637 FWD_TS(SetConnectionFlags, uint32_t); 638 FWD_TS(SetIsPrivate, bool); 639 FWD_TS_PTR(GetTlsFlags, uint32_t); 640 FWD_TS(SetTlsFlags, uint32_t); 641 FWD_TS_PTR(GetRecvBufferSize, uint32_t); 642 FWD_TS(SetRecvBufferSize, uint32_t); 643 FWD_TS_PTR(GetResetIPFamilyPreference, bool); 644 645 nsresult TLSTransportLayer::GetTlsSocketControl( 646 nsITLSSocketControl** tlsSocketControl) { 647 if (!mTLSSocketControl) { 648 return NS_ERROR_ABORT; 649 } 650 651 *tlsSocketControl = do_AddRef(mTLSSocketControl).take(); 652 return NS_OK; 653 } 654 655 nsresult TLSTransportLayer::GetOriginAttributes( 656 mozilla::OriginAttributes* aOriginAttributes) { 657 if (!mSocketTransport) { 658 return NS_ERROR_FAILURE; 659 } 660 return mSocketTransport->GetOriginAttributes(aOriginAttributes); 661 } 662 663 nsresult TLSTransportLayer::SetOriginAttributes( 664 const mozilla::OriginAttributes& aOriginAttributes) { 665 if (!mSocketTransport) { 666 return NS_ERROR_FAILURE; 667 } 668 return mSocketTransport->SetOriginAttributes(aOriginAttributes); 669 } 670 671 NS_IMETHODIMP 672 TLSTransportLayer::GetScriptableOriginAttributes( 673 JSContext* aCx, JS::MutableHandle<JS::Value> aOriginAttributes) { 674 if (!mSocketTransport) { 675 return NS_ERROR_FAILURE; 676 } 677 return mSocketTransport->GetScriptableOriginAttributes(aCx, 678 aOriginAttributes); 679 } 680 681 NS_IMETHODIMP 682 TLSTransportLayer::SetScriptableOriginAttributes( 683 JSContext* aCx, JS::Handle<JS::Value> aOriginAttributes) { 684 if (!mSocketTransport) { 685 return NS_ERROR_FAILURE; 686 } 687 return mSocketTransport->SetScriptableOriginAttributes(aCx, 688 aOriginAttributes); 689 } 690 691 NS_IMETHODIMP 692 TLSTransportLayer::GetHost(nsACString& aHost) { 693 if (!mSocketTransport) { 694 return NS_ERROR_FAILURE; 695 } 696 return mSocketTransport->GetHost(aHost); 697 } 698 699 NS_IMETHODIMP 700 TLSTransportLayer::GetTimeout(uint32_t aType, uint32_t* _retval) { 701 if (!mSocketTransport) { 702 return NS_ERROR_FAILURE; 703 } 704 return mSocketTransport->GetTimeout(aType, _retval); 705 } 706 707 NS_IMETHODIMP 708 TLSTransportLayer::SetTimeout(uint32_t aType, uint32_t aValue) { 709 if (!mSocketTransport) { 710 return NS_ERROR_FAILURE; 711 } 712 return mSocketTransport->SetTimeout(aType, aValue); 713 } 714 715 NS_IMETHODIMP 716 TLSTransportLayer::SetReuseAddrPort(bool aReuseAddrPort) { 717 if (!mSocketTransport) { 718 return NS_ERROR_FAILURE; 719 } 720 return mSocketTransport->SetReuseAddrPort(aReuseAddrPort); 721 } 722 723 NS_IMETHODIMP 724 TLSTransportLayer::SetLinger(bool aPolarity, int16_t aTimeout) { 725 if (!mSocketTransport) { 726 return NS_ERROR_FAILURE; 727 } 728 return mSocketTransport->SetLinger(aPolarity, aTimeout); 729 } 730 731 NS_IMETHODIMP 732 TLSTransportLayer::GetQoSBits(uint8_t* aQoSBits) { 733 if (!mSocketTransport) { 734 return NS_ERROR_FAILURE; 735 } 736 return mSocketTransport->GetQoSBits(aQoSBits); 737 } 738 739 NS_IMETHODIMP 740 TLSTransportLayer::SetQoSBits(uint8_t aQoSBits) { 741 if (!mSocketTransport) { 742 return NS_ERROR_FAILURE; 743 } 744 return mSocketTransport->SetQoSBits(aQoSBits); 745 } 746 747 NS_IMETHODIMP 748 TLSTransportLayer::GetRetryDnsIfPossible(bool* aRetry) { 749 if (!mSocketTransport) { 750 return NS_ERROR_FAILURE; 751 } 752 return mSocketTransport->GetRetryDnsIfPossible(aRetry); 753 } 754 755 NS_IMETHODIMP 756 TLSTransportLayer::GetStatus(nsresult* aStatus) { 757 if (!mSocketTransport) { 758 return NS_ERROR_FAILURE; 759 } 760 return mSocketTransport->GetStatus(aStatus); 761 } 762 763 int32_t TLSTransportLayer::OutputInternal(const char* aBuf, int32_t aAmount) { 764 LOG(("TLSTransportLayer::OutputInternal %p %d", this, aAmount)); 765 766 uint32_t outCountWrite = 0; 767 mOutputStatus = 768 mSocketOutWrapper.WriteDirectly(aBuf, aAmount, &outCountWrite); 769 if (NS_FAILED(mOutputStatus)) { 770 if (mOutputStatus == NS_BASE_STREAM_WOULD_BLOCK) { 771 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 772 } else { 773 PR_SetError(PR_UNKNOWN_ERROR, 0); 774 } 775 return -1; 776 } 777 778 return outCountWrite; 779 } 780 781 int32_t TLSTransportLayer::InputInternal(char* aBuf, int32_t aAmount) { 782 LOG(("TLSTransportLayer::InputInternal aAmount=%d\n", aAmount)); 783 784 uint32_t outCountRead = 0; 785 mInputStatus = mSocketInWrapper.ReadDirectly(aBuf, aAmount, &outCountRead); 786 if (NS_FAILED(mInputStatus)) { 787 if (mInputStatus == NS_BASE_STREAM_WOULD_BLOCK) { 788 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 789 } else { 790 PR_SetError(PR_UNKNOWN_ERROR, 0); 791 } 792 return -1; 793 } 794 return outCountRead; 795 } 796 797 PRStatus TLSTransportLayer::GetPeerName(PRFileDesc* aFD, PRNetAddr* addr) { 798 TLSTransportLayer* self = reinterpret_cast<TLSTransportLayer*>(aFD->secret); 799 NetAddr peeraddr; 800 if (NS_FAILED(self->Transport()->GetPeerAddr(&peeraddr))) { 801 return PR_FAILURE; 802 } 803 NetAddrToPRNetAddr(&peeraddr, addr); 804 return PR_SUCCESS; 805 } 806 807 PRStatus TLSTransportLayer::GetSocketOption(PRFileDesc* aFD, 808 PRSocketOptionData* aOpt) { 809 if (aOpt->option == PR_SockOpt_Nonblocking) { 810 aOpt->value.non_blocking = PR_TRUE; 811 return PR_SUCCESS; 812 } 813 return PR_FAILURE; 814 } 815 816 PRStatus TLSTransportLayer::SetSocketOption(PRFileDesc* aFD, 817 const PRSocketOptionData* aOpt) { 818 return PR_FAILURE; 819 } 820 821 PRStatus TLSTransportLayer::Close(PRFileDesc* aFD) { return PR_SUCCESS; } 822 823 int32_t TLSTransportLayer::Write(PRFileDesc* aFD, const void* aBuf, 824 int32_t aAmount) { 825 TLSTransportLayer* self = reinterpret_cast<TLSTransportLayer*>(aFD->secret); 826 return self->OutputInternal(static_cast<const char*>(aBuf), aAmount); 827 } 828 829 int32_t TLSTransportLayer::Send(PRFileDesc* aFD, const void* aBuf, 830 int32_t aAmount, int, PRIntervalTime) { 831 return Write(aFD, aBuf, aAmount); 832 } 833 834 int32_t TLSTransportLayer::Read(PRFileDesc* aFD, void* aBuf, int32_t aAmount) { 835 TLSTransportLayer* self = reinterpret_cast<TLSTransportLayer*>(aFD->secret); 836 return self->InputInternal(static_cast<char*>(aBuf), aAmount); 837 } 838 839 int32_t TLSTransportLayer::Recv(PRFileDesc* aFD, void* aBuf, int32_t aAmount, 840 int, PRIntervalTime) { 841 return Read(aFD, aBuf, aAmount); 842 } 843 844 int16_t TLSTransportLayer::Poll(PRFileDesc* fd, int16_t in_flags, 845 int16_t* out_flags) { 846 LOG(("TLSTransportLayer::Poll fd=%p inf_flags=%d\n", fd, (int)in_flags)); 847 *out_flags = in_flags; 848 849 TLSTransportLayer* self = reinterpret_cast<TLSTransportLayer*>(fd->secret); 850 if (!self) { 851 return 0; 852 } 853 854 if (in_flags & PR_POLL_READ) { 855 self->mSocketInWrapper.mSocketIn->AsyncWait(self, 0, 0, nullptr); 856 } else if (in_flags & PR_POLL_WRITE) { 857 self->mSocketOutWrapper.mSocketOut->AsyncWait(self, 0, 0, nullptr); 858 } 859 860 return in_flags; 861 } 862 863 bool TLSTransportLayer::HasDataToRecv() { 864 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 865 if (!mFD) { 866 return false; 867 } 868 int32_t n = 0; 869 char c; 870 n = PR_Recv(mFD, &c, 1, PR_MSG_PEEK, 0); 871 return n > 0; 872 } 873 874 } // namespace mozilla::net