File indexing completed on 2025-01-05 04:37:32

0001 /*
0002     SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <QObject>
0008 #include <QtTest>
0009 #include <util/log.h>
0010 #include <utp/localwindow.h>
0011 #include <utp/utpprotocol.h>
0012 
0013 using namespace utp;
0014 using namespace bt;
0015 
0016 class LocalWindowTest : public QObject
0017 {
0018     Q_OBJECT
0019 public:
0020 private Q_SLOTS:
0021     void initTestCase()
0022     {
0023         bt::InitLog("localwindowtest.log");
0024     }
0025 
0026     void testSeqNr()
0027     {
0028         Out(SYS_UTP | LOG_DEBUG) << "testSeqNr" << endl;
0029         QVERIFY(SeqNrCmpSE(4, 8));
0030         QVERIFY(SeqNrCmpSE(4, 4));
0031         QVERIFY(!SeqNrCmpSE(4, 2));
0032 
0033         QVERIFY(SeqNrCmpS(4, 8));
0034         QVERIFY(!SeqNrCmpS(4, 4));
0035         QVERIFY(!SeqNrCmpS(4, 2));
0036 
0037         QVERIFY(!SeqNrCmpSE(1, 65000));
0038         QVERIFY(SeqNrCmpSE(65000, 1));
0039         QVERIFY(!SeqNrCmpS(1, 65000));
0040         QVERIFY(SeqNrCmpS(65000, 1));
0041 
0042         QVERIFY(SeqNrDiff(65535, 0) == 1);
0043         QVERIFY(SeqNrDiff(0, 65535) == 1);
0044         QVERIFY(SeqNrDiff(65535, 6) == 7);
0045         QVERIFY(SeqNrDiff(6, 65535) == 7);
0046         QVERIFY(SeqNrDiff(65530, 5) == 11);
0047         QVERIFY(SeqNrDiff(5, 65530) == 11);
0048     }
0049 
0050     void testLocalWindow()
0051     {
0052         Out(SYS_UTP | LOG_DEBUG) << "testLocalWindow" << endl;
0053         bt::BufferPool pool;
0054         bt::Uint8 wdata[1000];
0055         memset(wdata, 0, 1000);
0056 
0057         utp::Header hdr;
0058         utp::LocalWindow wnd(1000);
0059         wnd.setLastSeqNr(1);
0060 
0061         // write 500 bytes to it
0062         hdr.seq_nr = 2;
0063         QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true);
0064         QVERIFY(wnd.availableSpace() == 500);
0065         QVERIFY(wnd.currentWindow() == 500);
0066 
0067         // write another 100 to it
0068         hdr.seq_nr++;
0069         QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true);
0070         QVERIFY(wnd.availableSpace() == 400);
0071         QVERIFY(wnd.currentWindow() == 600);
0072 
0073         // read 300 from it
0074         QVERIFY(wnd.read(wdata, 300) == 300);
0075         QVERIFY(wnd.availableSpace() == 700);
0076         QVERIFY(wnd.currentWindow() == 300);
0077     }
0078 
0079     void testPacketLoss()
0080     {
0081         Out(SYS_UTP | LOG_DEBUG) << "testPacketLoss" << endl;
0082         bt::BufferPool pool;
0083         bt::Uint8 wdata[1000];
0084 
0085         utp::Header hdr;
0086         utp::LocalWindow wnd(1000);
0087         wnd.setLastSeqNr(1);
0088 
0089         // write 500 bytes to it
0090         hdr.seq_nr = 2;
0091         QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true);
0092         QVERIFY(wnd.availableSpace() == 500);
0093         QVERIFY(wnd.currentWindow() == 500);
0094 
0095         // write 100 bytes to it bit with the wrong sequence number
0096         hdr.seq_nr = 4;
0097         QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true);
0098         QVERIFY(wnd.availableSpace() == 400);
0099         QVERIFY(wnd.currentWindow() == 600);
0100         QVERIFY(wnd.bytesAvailable() == 500);
0101 
0102         // Try to read all of it, but we should only get back 500
0103         QVERIFY(wnd.read(wdata, 600) == 500);
0104         QVERIFY(wnd.availableSpace() == 900);
0105         QVERIFY(wnd.currentWindow() == 100);
0106         QVERIFY(wnd.bytesAvailable() == 0);
0107 
0108         // write the missing packet
0109         hdr.seq_nr = 3;
0110         QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true);
0111         QVERIFY(wnd.availableSpace() == 800);
0112         QVERIFY(wnd.currentWindow() == 200);
0113         QVERIFY(wnd.bytesAvailable() == 200);
0114     }
0115 
0116     void testPacketLoss2()
0117     {
0118         Out(SYS_UTP | LOG_DEBUG) << "testPacketLoss2" << endl;
0119         bt::Uint8 wdata[1000];
0120         memset(wdata, 0, 1000);
0121 
0122         bt::BufferPool pool;
0123 
0124         utp::Header hdr;
0125         utp::LocalWindow wnd(1000);
0126         wnd.setLastSeqNr(0);
0127 
0128         // first write first and last packet
0129         bt::Uint32 step = 200;
0130         hdr.seq_nr = 1;
0131         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0132         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - step);
0133         QVERIFY(wnd.currentWindow() == step);
0134         hdr.seq_nr = 5;
0135         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0136         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 2 * step);
0137         QVERIFY(wnd.currentWindow() == 2 * step);
0138         QVERIFY(wnd.bytesAvailable() == step);
0139 
0140         // Now write 4
0141         hdr.seq_nr = 4;
0142         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0143         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 3 * step);
0144         QVERIFY(wnd.currentWindow() == 3 * step);
0145         QVERIFY(wnd.bytesAvailable() == step);
0146 
0147         // And then 3
0148         hdr.seq_nr = 3;
0149         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0150         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 4 * step);
0151         QVERIFY(wnd.currentWindow() == 4 * step);
0152         QVERIFY(wnd.bytesAvailable() == step);
0153 
0154         // And then 2
0155         hdr.seq_nr = 2;
0156         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0157         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 5 * step);
0158         QVERIFY(wnd.currentWindow() == 5 * step);
0159         QVERIFY(wnd.bytesAvailable() == 5 * step);
0160     }
0161 
0162     void testToMuchData()
0163     {
0164         Out(SYS_UTP | LOG_DEBUG) << "testToMuchData" << endl;
0165         bt::BufferPool pool;
0166         bt::Uint8 wdata[1000];
0167         memset(wdata, 0, 1000);
0168 
0169         utp::Header hdr;
0170         utp::LocalWindow wnd(500);
0171         wnd.setLastSeqNr(1);
0172 
0173         // write 500 bytes to it
0174         hdr.seq_nr = 2;
0175         QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true);
0176         QVERIFY(wnd.availableSpace() == 0);
0177         QVERIFY(wnd.currentWindow() == 500);
0178 
0179         // writing more data should now have no effect at all
0180         hdr.seq_nr = 3;
0181         QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == false);
0182         QVERIFY(wnd.availableSpace() == 0);
0183         QVERIFY(wnd.currentWindow() == 500);
0184     }
0185 
0186     void testSelectiveAck()
0187     {
0188         Out(SYS_UTP | LOG_DEBUG) << "testSelectiveAck" << endl;
0189         bt::BufferPool pool;
0190         bt::Uint8 wdata[1000];
0191         memset(wdata, 0, 1000);
0192 
0193         utp::Header hdr;
0194         utp::LocalWindow wnd(1000);
0195         wnd.setLastSeqNr(0);
0196 
0197         // first write first and last packet
0198         bt::Uint32 step = 200;
0199         hdr.seq_nr = 1;
0200         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0201         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - step);
0202         QVERIFY(wnd.currentWindow() == step);
0203         hdr.seq_nr = 5;
0204         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0205         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 2 * step);
0206         QVERIFY(wnd.currentWindow() == 2 * step);
0207         QVERIFY(wnd.bytesAvailable() == step);
0208 
0209         // Check SelectiveAck generation
0210         QVERIFY(wnd.selectiveAckBits() == 3);
0211         bt::Uint8 sack_data[6];
0212         SelectiveAck sack;
0213         sack.length = 4;
0214         sack.extension = 0;
0215         sack.bitmask = sack_data + 2;
0216         wnd.fillSelectiveAck(&sack);
0217         QVERIFY(sack_data[2] == 0x4);
0218         QVERIFY(sack_data[3] == 0x0);
0219         QVERIFY(sack_data[4] == 0x0);
0220         QVERIFY(sack_data[5] == 0x0);
0221 
0222         // Now write 4
0223         hdr.seq_nr = 4;
0224         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0225         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 3 * step);
0226         QVERIFY(wnd.currentWindow() == 3 * step);
0227         QVERIFY(wnd.bytesAvailable() == step);
0228 
0229         // Check selective ack again
0230         QVERIFY(wnd.selectiveAckBits() == 3);
0231         sack.length = 4;
0232         sack.extension = 0;
0233         wnd.fillSelectiveAck(&sack);
0234         QVERIFY(sack_data[2] == 0x6);
0235         QVERIFY(sack_data[3] == 0x0);
0236         QVERIFY(sack_data[4] == 0x0);
0237         QVERIFY(sack_data[5] == 0x0);
0238 
0239         // Now write 3
0240         hdr.seq_nr = 3;
0241         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0242         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 4 * step);
0243         QVERIFY(wnd.currentWindow() == 4 * step);
0244         QVERIFY(wnd.bytesAvailable() == step);
0245 
0246         // Check selective ack again
0247         QVERIFY(wnd.selectiveAckBits() == 3);
0248         sack.length = 4;
0249         sack.extension = 0;
0250         wnd.fillSelectiveAck(&sack);
0251         QVERIFY(sack_data[2] == 0x7);
0252         QVERIFY(sack_data[3] == 0x0);
0253         QVERIFY(sack_data[4] == 0x0);
0254         QVERIFY(sack_data[5] == 0x0);
0255 
0256         // And then 2
0257         hdr.seq_nr = 2;
0258         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0259         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 5 * step);
0260         QVERIFY(wnd.currentWindow() == 5 * step);
0261         QVERIFY(wnd.bytesAvailable() == 5 * step);
0262         // selective ack should now be unnecessary
0263         QVERIFY(wnd.selectiveAckBits() == 0);
0264     }
0265 
0266     void testSeqNrWrapAround()
0267     {
0268         Out(SYS_UTP | LOG_DEBUG) << "testSeqNrWrapAround" << endl;
0269         bt::BufferPool pool;
0270         bt::Uint8 wdata[1000];
0271         memset(wdata, 0, 1000);
0272 
0273         utp::Header hdr;
0274         utp::LocalWindow wnd(1000);
0275         wnd.setLastSeqNr(65535);
0276 
0277         // write 500 bytes to it
0278         hdr.seq_nr = 0;
0279         QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true);
0280         QVERIFY(wnd.availableSpace() == 500);
0281         QVERIFY(wnd.currentWindow() == 500);
0282 
0283         // write another 100 to it
0284         hdr.seq_nr++;
0285         QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true);
0286         QVERIFY(wnd.availableSpace() == 400);
0287         QVERIFY(wnd.currentWindow() == 600);
0288 
0289         // read 300 from it
0290         QVERIFY(wnd.read(wdata, 300) == 300);
0291         QVERIFY(wnd.availableSpace() == 700);
0292         QVERIFY(wnd.currentWindow() == 300);
0293     }
0294 
0295     void testSeqNrWrapAroundSelectiveAck()
0296     {
0297         Out(SYS_UTP | LOG_DEBUG) << "testSeqNrWrapAroundSelectiveAck" << endl;
0298         bt::BufferPool pool;
0299         bt::Uint8 wdata[1000];
0300         memset(wdata, 0, 1000);
0301 
0302         utp::Header hdr;
0303         utp::LocalWindow wnd(1000);
0304         wnd.setLastSeqNr(65535);
0305 
0306         // first write first and last packet
0307         bt::Uint32 step = 200;
0308         hdr.seq_nr = 0;
0309         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0310         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - step);
0311         QVERIFY(wnd.currentWindow() == step);
0312         hdr.seq_nr = 4;
0313         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0314         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 2 * step);
0315         QVERIFY(wnd.currentWindow() == 2 * step);
0316         QVERIFY(wnd.bytesAvailable() == step);
0317 
0318         // Check SelectiveAck generation
0319         QVERIFY(wnd.selectiveAckBits() == 3);
0320         bt::Uint8 sack_data[6];
0321         SelectiveAck sack;
0322         sack.length = 4;
0323         sack.extension = 0;
0324         sack.bitmask = sack_data + 2;
0325         wnd.fillSelectiveAck(&sack);
0326         QVERIFY(sack_data[2] == 0x4);
0327         QVERIFY(sack_data[3] == 0x0);
0328         QVERIFY(sack_data[4] == 0x0);
0329         QVERIFY(sack_data[5] == 0x0);
0330 
0331         // Now write 4
0332         hdr.seq_nr = 3;
0333         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0334         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 3 * step);
0335         QVERIFY(wnd.currentWindow() == 3 * step);
0336         QVERIFY(wnd.bytesAvailable() == step);
0337 
0338         // Check selective ack again
0339         QVERIFY(wnd.selectiveAckBits() == 3);
0340         sack.length = 4;
0341         sack.extension = 0;
0342         wnd.fillSelectiveAck(&sack);
0343         QVERIFY(sack_data[2] == 0x6);
0344         QVERIFY(sack_data[3] == 0x0);
0345         QVERIFY(sack_data[4] == 0x0);
0346         QVERIFY(sack_data[5] == 0x0);
0347 
0348         // Now write 3
0349         hdr.seq_nr = 2;
0350         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0351         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 4 * step);
0352         QVERIFY(wnd.currentWindow() == 4 * step);
0353         QVERIFY(wnd.bytesAvailable() == step);
0354 
0355         // Check selective ack again
0356         QVERIFY(wnd.selectiveAckBits() == 3);
0357         sack.length = 4;
0358         sack.extension = 0;
0359         wnd.fillSelectiveAck(&sack);
0360         QVERIFY(sack_data[2] == 0x7);
0361         QVERIFY(sack_data[3] == 0x0);
0362         QVERIFY(sack_data[4] == 0x0);
0363         QVERIFY(sack_data[5] == 0x0);
0364 
0365         // And then 2
0366         hdr.seq_nr = 1;
0367         QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true);
0368         QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 5 * step);
0369         QVERIFY(wnd.currentWindow() == 5 * step);
0370         QVERIFY(wnd.bytesAvailable() == 5 * step);
0371         // selective ack should now be unnecessary
0372         QVERIFY(wnd.selectiveAckBits() == 0);
0373     }
0374 
0375 private:
0376     // bt::Uint8 data[13];
0377     // bt::Uint8 data2[6];
0378 };
0379 
0380 QTEST_MAIN(LocalWindowTest)
0381 
0382 #include "localwindowtest.moc"