00001 #ifndef SST_FLOW_H
00002 #define SST_FLOW_H
00003
00004 #include <QTime>
00005 #include <QTimer>
00006
00007 #include "ident.h"
00008 #include "sock.h"
00009 #include "timer.h"
00010
00011
00012 #include "chk32.h"
00013 #include "aes.h"
00014 #include "hmac.h"
00015
00016
00017 namespace SST {
00018
00019 class Host;
00020 class Ident;
00021 class Endpoint;
00022 class Socket;
00023 class FlowCC;
00024 class KeyInitiator;
00025
00026
00027
00028 class FlowArmor
00029 {
00030 friend class Flow;
00031
00032 protected:
00033
00034
00035
00036
00037
00038
00039
00040 static const int encofs = 4;
00041
00042 virtual QByteArray txenc(qint64 pktseq, const QByteArray &pkt) = 0;
00043 virtual bool rxdec(qint64 pktseq, QByteArray &pkt) = 0;
00044
00045 virtual ~FlowArmor();
00046 };
00047
00048
00049
00050 class Flow : public SocketFlow
00051 {
00052 friend class KeyInitiator;
00053 Q_OBJECT
00054
00055 private:
00056 Host *const h;
00057 FlowArmor *armr;
00058 FlowCC *cc;
00059
00060
00061 public:
00062
00063
00064
00065 static const int hdrlen = 8;
00066
00067
00068
00069 static const quint32 chanBits = 8;
00070 static const quint32 chanMask = (1 << chanBits) - 1;
00071 static const quint32 chanMax = chanMask;
00072 static const quint32 chanShift = 24;
00073 static const quint32 seqBits = 24;
00074 static const quint32 seqMask = (1 << seqBits) - 1;
00075
00076
00077
00078 static const quint32 resvBits = 4;
00079 static const quint32 ackctBits = 4;
00080 static const quint32 ackctMask = (1 << ackctBits) - 1;
00081 static const quint32 ackctMax = ackctMask;
00082 static const quint32 ackctShift = 24;
00083 static const quint32 ackSeqBits = 24;
00084 static const quint32 ackSeqMask = (1 << ackSeqBits) - 1;
00085
00086
00087 Flow(Host *host, QObject *parent = NULL);
00088
00089 inline Host *host() { return h; }
00090
00091
00092
00093 inline void setArmor(FlowArmor *armor) { this->armr = armor; }
00094 inline FlowArmor *armor() { return armr; }
00095
00096
00097
00098 inline void setCongestionController(FlowCC *cc) { this->cc = cc; }
00099 inline FlowCC *congestionController() { return cc; }
00100
00101
00102 virtual void start();
00103 virtual void stop();
00104
00105
00106 protected:
00107
00108
00109 static const int maskBits = 32;
00110
00111
00112 quint64 txseq;
00113 quint64 txdatseq;
00114 quint64 txackseq;
00115 quint64 recovseq;
00116 quint64 markseq;
00117 quint64 markbase;
00118 Time marktime;
00119 quint32 txackmask;
00120 quint32 markacks;
00121 quint32 marksent;
00122 quint32 cwnd;
00123 bool cwndlim;
00124
00125
00126 quint32 ssthresh;
00127
00128
00129 quint32 ssbase;
00130
00131
00132 int cwndinc;
00133 int lastrtt;
00134 float lastpps;
00135 quint32 basewnd;
00136 float basertt, basepps, basepwr;
00137
00138
00139 float cwndmax;
00140
00141
00142 Timer rtxtimer;
00143
00144
00145 quint64 rxseq;
00146 quint32 rxmask;
00147 quint8 rxackct;
00148 quint8 rxunacked;
00149
00150
00151 bool delayack;
00152 Timer acktimer;
00153
00154
00155 float cumrtt;
00156 float cumrttvar;
00157 float cumpps;
00158 float cumppsvar;
00159 float cumpwr;
00160 float cumbps;
00161 float cumloss;
00162 Timer statstimer;
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bool flowTransmit(const QByteArray &pkt, quint64 &pktseq);
00177
00178
00179
00180 int mayTransmit();
00181
00182
00183
00184
00185
00186 inline qint64 unackedPackets()
00187 { return txseq - txackseq; }
00188
00189
00190
00191
00192
00193
00194 inline qint64 unackedDataPackets()
00195 { return (txdatseq > txackseq) ? (txdatseq - txackseq) : 0; }
00196
00197
00198 qint64 markElapsed();
00199
00200 public:
00201 inline bool deleyedAcks() const { return delayack; }
00202 inline void setDelayedAcks(bool enabled) { delayack = enabled; }
00203
00204 protected:
00205
00206 virtual void flowReceive(qint64 pktseq, QByteArray &pkt) = 0;
00207
00208 virtual void readyTransmit();
00209 virtual void acked(qint64 txseq, int npackets);
00210 virtual void missed(qint64 txseq, int npackets);
00211 virtual void failed();
00212
00213
00214 private:
00215
00216 virtual void receive(QByteArray &msg, const SocketEndpoint &src);
00217
00218
00219 bool tx(const QByteArray &pkt, quint32 packseq,
00220 quint64 &pktseq);
00221 bool txack(quint32 seq, unsigned ackct);
00222 inline void flushack()
00223 { if (rxunacked) { rxunacked = 0; txack(rxseq, rxackct); }
00224 acktimer.stop(); }
00225
00226 inline void rtxstart()
00227 { rtxtimer.start((int)(cumrtt * 2.0)); }
00228
00229
00230 private slots:
00231 void rtxTimeout(bool failed);
00232 void ackTimeout();
00233 void statsTimeout();
00234 };
00235
00236
00237
00238
00239
00240
00241
00242
00243 class ChecksumArmor : public FlowArmor
00244 {
00245 const uint32_t txkey, rxkey;
00246
00247 public:
00248 ChecksumArmor(uint32_t txkey, uint32_t rxkey);
00249
00250 virtual QByteArray txenc(qint64 pktseq, const QByteArray &pkt);
00251 virtual bool rxdec(qint64 pktseq, QByteArray &pkt);
00252 };
00253
00254
00255 class AESArmor : public FlowArmor
00256 {
00257 const AES txaes, rxaes;
00258 const HMAC txmac, rxmac;
00259
00260 union ivec {
00261 quint8 b[AES_BLOCK_SIZE];
00262 quint32 l[4];
00263 } ivec;
00264
00265 public:
00266 AESArmor(const QByteArray &txenckey, const QByteArray &txmackey,
00267 const QByteArray &rxenckey, const QByteArray &rxmackey);
00268
00269 virtual QByteArray txenc(qint64 pktseq, const QByteArray &pkt);
00270 virtual bool rxdec(qint64 pktseq, QByteArray &pkt);
00271 };
00272
00273 }
00274
00275 #endif // SST_FLOW_H