aboutsummaryrefslogtreecommitdiff
path: root/osp/impl/quic/quic_service_common.h
blob: d4644845aae1625e428ec3449d5a8f169e249a77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef OSP_IMPL_QUIC_QUIC_SERVICE_COMMON_H_
#define OSP_IMPL_QUIC_QUIC_SERVICE_COMMON_H_

#include <cstdint>
#include <map>
#include <memory>
#include <vector>

#include "osp/impl/quic/quic_connection.h"
#include "osp/public/protocol_connection.h"

namespace openscreen {

class ServiceConnectionDelegate;

class QuicProtocolConnection final : public ProtocolConnection {
 public:
  class Owner {
   public:
    virtual ~Owner() = default;

    // Called right before |connection| is destroyed (destructor runs).
    virtual void OnConnectionDestroyed(QuicProtocolConnection* connection) = 0;
  };

  static std::unique_ptr<QuicProtocolConnection> FromExisting(
      Owner* owner,
      QuicConnection* connection,
      ServiceConnectionDelegate* delegate,
      uint64_t endpoint_id);

  QuicProtocolConnection(Owner* owner,
                         uint64_t endpoint_id,
                         uint64_t connection_id);
  ~QuicProtocolConnection() override;

  // ProtocolConnection overrides.
  void Write(const uint8_t* data, size_t data_size) override;
  void CloseWriteEnd() override;

  QuicStream* stream() { return stream_; }
  void set_stream(QuicStream* stream) { stream_ = stream; }

  void OnClose();

 private:
  Owner* const owner_;
  QuicStream* stream_ = nullptr;
};

struct ServiceStreamPair {
  ServiceStreamPair(std::unique_ptr<QuicStream> stream,
                    QuicProtocolConnection* protocol_connection);
  ~ServiceStreamPair();
  ServiceStreamPair(ServiceStreamPair&&);
  ServiceStreamPair& operator=(ServiceStreamPair&&);

  std::unique_ptr<QuicStream> stream;
  uint64_t connection_id;
  QuicProtocolConnection* protocol_connection;
};

class ServiceConnectionDelegate final : public QuicConnection::Delegate,
                                        public QuicStream::Delegate {
 public:
  class ServiceDelegate : public QuicProtocolConnection::Owner {
   public:
    ~ServiceDelegate() override = default;

    virtual uint64_t OnCryptoHandshakeComplete(
        ServiceConnectionDelegate* delegate,
        uint64_t connection_id) = 0;
    virtual void OnIncomingStream(
        std::unique_ptr<QuicProtocolConnection> connection) = 0;
    virtual void OnConnectionClosed(uint64_t endpoint_id,
                                    uint64_t connection_id) = 0;
    virtual void OnDataReceived(uint64_t endpoint_id,
                                uint64_t connection_id,
                                const uint8_t* data,
                                size_t data_size) = 0;
  };

  ServiceConnectionDelegate(ServiceDelegate* parent,
                            const IPEndpoint& endpoint);
  ~ServiceConnectionDelegate() override;

  void AddStreamPair(ServiceStreamPair&& stream_pair);
  void DropProtocolConnection(QuicProtocolConnection* connection);

  // This should be called at the end of each event loop that effects this
  // connection so streams that were closed by the other endpoint can be
  // destroyed properly.
  void DestroyClosedStreams();

  const IPEndpoint& endpoint() const { return endpoint_; }

  bool has_streams() const { return !streams_.empty(); }

  // QuicConnection::Delegate overrides.
  void OnCryptoHandshakeComplete(uint64_t connection_id) override;
  void OnIncomingStream(uint64_t connection_id,
                        std::unique_ptr<QuicStream> stream) override;
  void OnConnectionClosed(uint64_t connection_id) override;
  QuicStream::Delegate* NextStreamDelegate(uint64_t connection_id,
                                           uint64_t stream_id) override;

  // QuicStream::Delegate overrides.
  void OnReceived(QuicStream* stream,
                  const char* data,
                  size_t data_size) override;
  void OnClose(uint64_t stream_id) override;

 private:
  ServiceDelegate* const parent_;
  IPEndpoint endpoint_;
  uint64_t endpoint_id_;
  std::unique_ptr<QuicProtocolConnection> pending_connection_;
  std::map<uint64_t, ServiceStreamPair> streams_;
  std::vector<ServiceStreamPair> closed_streams_;
};

struct ServiceConnectionData {
  explicit ServiceConnectionData(
      std::unique_ptr<QuicConnection> connection,
      std::unique_ptr<ServiceConnectionDelegate> delegate);
  ServiceConnectionData(ServiceConnectionData&&);
  ~ServiceConnectionData();
  ServiceConnectionData& operator=(ServiceConnectionData&&);

  std::unique_ptr<QuicConnection> connection;
  std::unique_ptr<ServiceConnectionDelegate> delegate;
};

}  // namespace openscreen

#endif  // OSP_IMPL_QUIC_QUIC_SERVICE_COMMON_H_