transportlayerprsock.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. // Original author: ekr@rtfm.com
  6. #include "logging.h"
  7. #include "nspr.h"
  8. #include "prerror.h"
  9. #include "prio.h"
  10. #include "nsCOMPtr.h"
  11. #include "nsASocketHandler.h"
  12. #include "nsISocketTransportService.h"
  13. #include "nsNetCID.h"
  14. #include "nsServiceManagerUtils.h"
  15. #include "nsXPCOM.h"
  16. #include "transportflow.h"
  17. #include "transportlayerprsock.h"
  18. namespace mozilla {
  19. MOZ_MTLOG_MODULE("mtransport")
  20. nsresult TransportLayerPrsock::InitInternal() {
  21. // Get the transport service as a transport service
  22. nsresult rv;
  23. stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
  24. if (!NS_SUCCEEDED(rv)) {
  25. MOZ_MTLOG(ML_ERROR, "Couldn't get socket transport service");
  26. return rv;
  27. }
  28. return NS_OK;
  29. }
  30. void TransportLayerPrsock::Import(PRFileDesc *fd, nsresult *result) {
  31. if (state_ != TS_INIT) {
  32. *result = NS_ERROR_NOT_INITIALIZED;
  33. return;
  34. }
  35. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Importing()");
  36. fd_ = fd;
  37. handler_ = new SocketHandler(this, fd);
  38. nsresult rv = stservice_->AttachSocket(fd_, handler_);
  39. if (!NS_SUCCEEDED(rv)) {
  40. *result = rv;
  41. return;
  42. }
  43. TL_SET_STATE(TS_OPEN);
  44. *result = NS_OK;
  45. }
  46. int TransportLayerPrsock::SendPacket(const unsigned char *data, size_t len) {
  47. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "SendPacket(" << len << ")");
  48. if (state_ != TS_OPEN) {
  49. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Can't send packet on closed interface");
  50. return TE_INTERNAL;
  51. }
  52. int32_t status;
  53. status = PR_Write(fd_, data, len);
  54. if (status >= 0) {
  55. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Wrote " << len << " bytes");
  56. return status;
  57. }
  58. PRErrorCode err = PR_GetError();
  59. if (err == PR_WOULD_BLOCK_ERROR) {
  60. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Write blocked");
  61. return TE_WOULDBLOCK;
  62. }
  63. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Write error; channel closed");
  64. TL_SET_STATE(TS_ERROR);
  65. return TE_ERROR;
  66. }
  67. void TransportLayerPrsock::OnSocketReady(PRFileDesc *fd, int16_t outflags) {
  68. if (!(outflags & PR_POLL_READ)) {
  69. return;
  70. }
  71. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "OnSocketReady(flags=" << outflags << ")");
  72. unsigned char buf[1600];
  73. int32_t rv = PR_Read(fd, buf, sizeof(buf));
  74. if (rv > 0) {
  75. // Successful read
  76. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read " << rv << " bytes");
  77. SignalPacketReceived(this, buf, rv);
  78. } else if (rv == 0) {
  79. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read 0 bytes; channel closed");
  80. TL_SET_STATE(TS_CLOSED);
  81. } else {
  82. PRErrorCode err = PR_GetError();
  83. if (err != PR_WOULD_BLOCK_ERROR) {
  84. MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read error; channel closed");
  85. TL_SET_STATE(TS_ERROR);
  86. }
  87. }
  88. }
  89. NS_IMPL_ISUPPORTS0(TransportLayerPrsock::SocketHandler)
  90. } // close namespace