quic_chromium_packet_writer.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef NET_QUIC_QUIC_CHROMIUM_PACKET_WRITER_H_
  5. #define NET_QUIC_QUIC_CHROMIUM_PACKET_WRITER_H_
  6. #include <stddef.h>
  7. #include "base/memory/raw_ptr.h"
  8. #include "base/memory/weak_ptr.h"
  9. #include "base/timer/timer.h"
  10. #include "net/base/completion_repeating_callback.h"
  11. #include "net/base/io_buffer.h"
  12. #include "net/base/net_export.h"
  13. #include "net/socket/datagram_client_socket.h"
  14. #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
  15. #include "net/third_party/quiche/src/quiche/quic/core/quic_packet_writer.h"
  16. #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
  17. #include "net/third_party/quiche/src/quiche/quic/core/quic_types.h"
  18. namespace net {
  19. // Chrome specific packet writer which uses a datagram Socket for writing data.
  20. class NET_EXPORT_PRIVATE QuicChromiumPacketWriter
  21. : public quic::QuicPacketWriter {
  22. public:
  23. // Define a specific IO buffer that can be allocated once, but be
  24. // assigned new contents and reused, avoiding the alternative of
  25. // repeated memory allocations. This packet writer only ever has a
  26. // single write in flight, a constraint inherited from the interface
  27. // of the underlying datagram Socket.
  28. class NET_EXPORT_PRIVATE ReusableIOBuffer : public IOBuffer {
  29. public:
  30. explicit ReusableIOBuffer(size_t capacity);
  31. size_t capacity() const { return capacity_; }
  32. size_t size() const { return size_; }
  33. // Does memcpy from |buffer| into this->data(). |buf_len <=
  34. // capacity()| must be true, |HasOneRef()| must be true.
  35. void Set(const char* buffer, size_t buf_len);
  36. private:
  37. ~ReusableIOBuffer() override;
  38. size_t capacity_;
  39. size_t size_ = 0;
  40. };
  41. // Delegate interface which receives notifications on socket write events.
  42. class NET_EXPORT_PRIVATE Delegate {
  43. public:
  44. // Called when a socket write attempt results in a failure, so
  45. // that the delegate may recover from it by perhaps rewriting the
  46. // packet to a different socket. An implementation must return the
  47. // return value from the rewrite attempt if there is one, and
  48. // |error_code| otherwise.
  49. virtual int HandleWriteError(
  50. int error_code,
  51. scoped_refptr<ReusableIOBuffer> last_packet) = 0;
  52. // Called to propagate the final write error to the delegate.
  53. virtual void OnWriteError(int error_code) = 0;
  54. // Called when the writer is unblocked due to a write completion.
  55. virtual void OnWriteUnblocked() = 0;
  56. };
  57. // |socket| and |task_runner| must outlive writer.
  58. QuicChromiumPacketWriter(DatagramClientSocket* socket,
  59. base::SequencedTaskRunner* task_runner);
  60. QuicChromiumPacketWriter(const QuicChromiumPacketWriter&) = delete;
  61. QuicChromiumPacketWriter& operator=(const QuicChromiumPacketWriter&) = delete;
  62. ~QuicChromiumPacketWriter() override;
  63. // |delegate| must outlive writer.
  64. void set_delegate(Delegate* delegate) { delegate_ = delegate; }
  65. // This method may unblock the packet writer if |force_write_blocked| is
  66. // false.
  67. void set_force_write_blocked(bool force_write_blocked);
  68. // Writes |packet| to the socket and handles write result if the write
  69. // completes synchronously.
  70. void WritePacketToSocket(scoped_refptr<ReusableIOBuffer> packet);
  71. // quic::QuicPacketWriter
  72. quic::WriteResult WritePacket(const char* buffer,
  73. size_t buf_len,
  74. const quic::QuicIpAddress& self_address,
  75. const quic::QuicSocketAddress& peer_address,
  76. quic::PerPacketOptions* options) override;
  77. bool IsWriteBlocked() const override;
  78. void SetWritable() override;
  79. absl::optional<int> MessageTooBigErrorCode() const override;
  80. quic::QuicByteCount GetMaxPacketSize(
  81. const quic::QuicSocketAddress& peer_address) const override;
  82. bool SupportsReleaseTime() const override;
  83. bool IsBatchMode() const override;
  84. quic::QuicPacketBuffer GetNextWriteLocation(
  85. const quic::QuicIpAddress& self_address,
  86. const quic::QuicSocketAddress& peer_address) override;
  87. quic::WriteResult Flush() override;
  88. void OnWriteComplete(int rv);
  89. private:
  90. void SetPacket(const char* buffer, size_t buf_len);
  91. bool MaybeRetryAfterWriteError(int rv);
  92. void RetryPacketAfterNoBuffers();
  93. quic::WriteResult WritePacketToSocketImpl();
  94. raw_ptr<DatagramClientSocket> socket_; // Unowned.
  95. raw_ptr<Delegate> delegate_ = nullptr; // Unowned.
  96. // Reused for every packet write for the lifetime of the writer. Is
  97. // moved to the delegate in the case of a write error.
  98. scoped_refptr<ReusableIOBuffer> packet_;
  99. // Whether a write is currently in progress: true if an asynchronous write is
  100. // in flight, or a retry of a previous write is in progress, or session is
  101. // handling write error of a previous write.
  102. bool write_in_progress_ = false;
  103. // If ture, IsWriteBlocked() will return true regardless of
  104. // |write_in_progress_|.
  105. bool force_write_blocked_ = false;
  106. int retry_count_ = 0;
  107. // Timer set when a packet should be retried after ENOBUFS.
  108. base::OneShotTimer retry_timer_;
  109. CompletionRepeatingCallback write_callback_;
  110. base::WeakPtrFactory<QuicChromiumPacketWriter> weak_factory_{this};
  111. };
  112. } // namespace net
  113. #endif // NET_QUIC_QUIC_CHROMIUM_PACKET_WRITER_H_