-
Notifications
You must be signed in to change notification settings - Fork 3
/
Connection.h
144 lines (109 loc) · 2.9 KB
/
Connection.h
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
141
142
143
144
//
// Created by frank on 17-8-13.
//
#ifndef FDP_CONNECTION_H
#define FDP_CONNECTION_H
#include "Congestion.h"
#include "RttEstimator.h"
#include "Timer.h"
#include "Segment.h"
#include "State.h"
#include <list>
#include <deque>
#include <functional>
#include <algorithm>
#include <vector>
class Connection;
typedef std::function<void(Connection&, const char *, size_t)> OutputCallback;
enum Error {
ERR_AGAIN = -1,
ERR_TRUNCED = -2,
ERR_TIMEOUT = -3,
ERR_MSGSIZE = -4,
};
class Connection: noncopyable
{
public:
Connection(uint32_t ident, uint32_t mtu = 1400, uint32_t interval = 10);
~Connection();
/* return size,
* return ERR_PIPE
* return ERR_MSGSIZE */
int send(const char *data, uint32_t size);
/* return size,
* return 0 for FIN,
* return -1 for EAGAIN
* return -2 for short buffer
* return -3 for timeout */
int recv(char *buffer, uint32_t size);
int peekLength() const;
void input(const char *data, uint32_t size);
void update(uint32_t current);
uint32_t check() const;
void stopSend();
bool getStopSend() const { return userStopSend_; }
void setSendWind(uint32_t sendWind);
void setRecvWind(uint32_t recvWind);
void setOutputCallback(OutputCallback cb)
{ outputCb_ = std::move(cb); }
bool normalClosed() const
{ return state.get() == STATE_NORMAL_CLOSED; }
bool timeoutClosed() const
{ return state.get() == STATE_TIMEOUT_CLOSED; }
uint32_t ident() const { return ident_; }
size_t sendQueueSize() const { return sendQueue_.size(); }
size_t recvQueueSize() const { return recvQueue_.size(); }
size_t mss() const { return mss_; }
private:
void flush();
void flushPendingAcks();
void flushWindProbe();
void flushWindTell();
void flushSendBuffer();
void output(const Segment& seg);
void moveRecvBufferToQueue();
void moveSendQueueToBuffer();
uint32_t recvWindUnused();
int unackSendBuffer(uint32_t unack);
int ackSendBuffer(uint32_t ack);
void insertRecvBuffer(SegmentPtr seg);
void appendAck(uint32_t seq, uint32_t ts)
{ ackQueue_.push_back({seq, ts}); }
void incrFastAck(uint32_t maxAck);
const uint32_t ident_;
const uint32_t mtu_;
const uint32_t mss_;
const uint32_t interval_;
RttEstimator rtte_;
Congestion cong_;
uint32_t current_;
Timer flushTimer_;
Timer probeTimer_;
uint32_t probeWait_;
bool updated;
typedef std::deque<SegmentPtr> SegQueue;
typedef std::list<SegmentPtr> SegList;
struct ACK { uint32_t ack, ts; };
typedef std::deque<ACK> AckQueue;
OutputCallback outputCb_;
std::vector<char> buffer;
SegQueue sendQueue_, recvQueue_;
SegList sendBuffer_, recvBuffer_;
AckQueue ackQueue_;
uint32_t sendUnak_;
uint32_t sendNext_;
uint32_t sendEnd_;
uint32_t sendWind_;
uint32_t recvNext_;
uint32_t recvEnd_;
uint32_t recvWind_;
uint32_t rmtWind_;
bool needWindTell;
bool sendEndValid_;
bool recvEndValid_;
bool userStopSend_;
uint32_t fastRsendTimes_;
uint32_t timeoutRsendTimes_;
State state;
};
#endif //FDP_CONNECTION_H