libktorrent  2.2.0
utpprotocol.h
1 /***************************************************************************
2  * Copyright (C) 2009 by Joris Guisson *
3  * joris.guisson@gmail.com *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #ifndef UTP_UTPPROTOCOL_H
22 #define UTP_UTPPROTOCOL_H
23 
24 #include <QtGlobal>
25 #include <QString>
26 #include <ktorrent_export.h>
27 #include <util/constants.h>
28 
29 
30 namespace utp
31 {
32  /*
33  UTP header:
34 
35  0 4 8 16 24 32
36  +-------+-------+---------------+---------------+---------------+
37  | ver | type | extension | connection_id |
38  +-------+-------+---------------+---------------+---------------+
39  | timestamp_microseconds |
40  +---------------+---------------+---------------+---------------+
41  | timestamp_difference_microseconds |
42  +---------------+---------------+---------------+---------------+
43  | wnd_size |
44  +---------------+---------------+---------------+---------------+
45  | seq_nr | ack_nr |
46  +---------------+---------------+---------------+---------------+
47  */
48 
49  struct KTORRENT_EXPORT Header
50  {
51  unsigned int version: 4;
52  unsigned int type: 4;
53  bt::Uint8 extension;
54  bt::Uint16 connection_id;
55  bt::Uint32 timestamp_microseconds;
56  bt::Uint32 timestamp_difference_microseconds;
57  bt::Uint32 wnd_size;
58  bt::Uint16 seq_nr;
59  bt::Uint16 ack_nr;
60 
61  void read(const bt::Uint8* data);
62  void write(bt::Uint8* data) const;
63  static bt::Uint32 size();
64  };
65 
66  struct SelectiveAck
67  {
68  bt::Uint8* bitmask;
69  bt::Uint8 extension;
70  bt::Uint8 length;
71 
72  SelectiveAck(): bitmask(NULL), extension(0), length(0){}
73  };
74 
76  {
77  bt::Uint8 extension;
78  bt::Uint8 length;
79  bt::Uint8 extension_bitmask[8];
80  };
81 
83  {
84  bt::Uint8 extension;
85  bt::Uint8 length;
86  };
87 
88  const bt::Uint8 SELECTIVE_ACK_ID = 1;
89  const bt::Uint8 EXTENSION_BITS_ID = 2;
90 
91  // type field values
92  const bt::Uint8 ST_DATA = 0;
93  const bt::Uint8 ST_FIN = 1;
94  const bt::Uint8 ST_STATE = 2;
95  const bt::Uint8 ST_RESET = 3;
96  const bt::Uint8 ST_SYN = 4;
97 
98  KTORRENT_EXPORT QString TypeToString(bt::Uint8 type);
99 
100  enum ConnectionState
101  {
102  CS_IDLE,
103  CS_SYN_SENT,
104  CS_CONNECTED,
105  CS_FINISHED,
106  CS_CLOSED
107  };
108 
109  const bt::Uint32 MIN_PACKET_SIZE = 150;
110  const bt::Uint32 MAX_PACKET_SIZE = 16384;
111 
112  const bt::Uint32 DELAY_WINDOW_SIZE = 2*60*1000; // 2 minutes
113  const bt::Uint32 CCONTROL_TARGET = 100;
114  const bt::Uint32 MAX_CWND_INCREASE_PACKETS_PER_RTT = 500;
115  const bt::Uint32 MAX_TIMEOUT = 30000;
116  const bt::Uint32 CONNECT_TIMEOUT = 30000;
117  const bt::Uint32 KEEP_ALIVE_TIMEOUT = 30000;
118 
119  const bt::Uint32 IP_AND_UDP_OVERHEAD = 28;
120 
121  /*
122  Test if a bit is acked
123  UTP standard:
124  The bitmask has reverse byte order. The first byte represents packets [ack_nr + 2, ack_nr + 2 + 7] in reverse order. The least significant bit in the byte represents ack_nr + 2, the most significant bit in the byte represents ack_nr + 2 + 7. The next byte in the mask represents [ack_nr + 2 + 8, ack_nr + 2 + 15] in reverse order, and so on. The bitmask is not limited to 32 bits but can be of any size.
125 
126  Here is the layout of a bitmask representing the first 32 packet acks represented in a selective ACK bitfield:
127 
128  0 8 16
129  +---------------+---------------+---------------+---------------+
130  | 9 8 ... 3 2 | 17 ... 10 | 25 ... 18 | 33 ... 26 |
131  +---------------+---------------+---------------+---------------+
132 
133  The number in the diagram maps the bit in the bitmask to the offset to add to ack_nr in order to calculate the sequence number that the bit is ACKing.
134  */
135  inline bool Acked(const SelectiveAck* sack, bt::Uint16 bit)
136  {
137  // check bounds
138  if (bit < 2 || bit > 8*sack->length + 1)
139  return false;
140 
141  const bt::Uint8* bitset = sack->bitmask;
142  int byte = (bit - 2) / 8;
143  int bit_off = (bit - 2) % 8;
144  return bitset[byte] & (0x01 << bit_off);
145  }
146 
147  // Turn on a bit in the SelectiveAck
148  inline void Ack(SelectiveAck* sack, bt::Uint16 bit)
149  {
150  // check bounds
151  if (bit < 2 || bit > 8*sack->length + 1)
152  return;
153 
154  bt::Uint8* bitset = sack->bitmask;
155  int byte = (bit - 2) / 8;
156  int bit_off = (bit - 2) % 8;
157  bitset[byte] |= (0x01 << bit_off);
158  }
159 
163  class KTORRENT_EXPORT PacketParser
164  {
165  public:
166  PacketParser(const QByteArray & packet);
167  PacketParser(const bt::Uint8* packet, bt::Uint32 size);
168  ~PacketParser();
169 
171  bool parse();
172 
173  const Header* header() const {return &hdr;}
174  const SelectiveAck* selectiveAck() const;
175  bt::Uint32 dataOffset() const {return data_off;}
176  bt::Uint32 dataSize() const {return data_size;}
177 
178  private:
179  const bt::Uint8* packet;
180  Header hdr;
181  SelectiveAck sack;
182  bool sack_found;
183  bt::Uint32 size;
184  bt::Uint32 data_off;
185  bt::Uint32 data_size;
186  };
187 
189  inline bool SeqNrCmpSE(bt::Uint16 a, bt::Uint16 b)
190  {
191  if (qAbs(b - a) < 32768)
192  return a <= b;
193  else
194  return a > b;
195  }
196 
198  inline bool SeqNrCmpS(bt::Uint16 a, bt::Uint16 b)
199  {
200  if (qAbs(b - a) < 32768)
201  return a < b;
202  else
203  return a > b;
204  }
205 
207  inline bt::Uint16 SeqNrDiff(bt::Uint16 a, bt::Uint16 b)
208  {
209  if (qAbs(b - a) < 32768)
210  return b - a;
211  else if (b > a)
212  return a + (65536 - b);
213  else
214  return b + (65536 - a);
215  }
216 }
217 
218 #endif // UTP_UTPPROTOCOL_H
utp::PacketParser::parse
bool parse()
Parses the packet, returns false on error.
utp::PacketParser
Definition: utpprotocol.h:164
utp::SelectiveAck
Definition: utpprotocol.h:67
utp::ExtensionBits
Definition: utpprotocol.h:76
utp::UnknownExtension
Definition: utpprotocol.h:83
utp::Header
Definition: utpprotocol.h:50