summaryrefslogtreecommitdiffstats
blob: c7e252c14bbd6adfc4f1db5eb687fac0557dda6d (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
/*
 * Copyright (c) 2010-2016 Isode Limited.
 * All rights reserved.
 * See the COPYING file for more information.
 */

#pragma once

#include <memory>

#include <boost/signals2.hpp>

#include <Swiften/Base/API.h>
#include <Swiften/FileTransfer/FileTransferError.h>
#include <Swiften/FileTransfer/ReadBytestream.h>
#include <Swiften/FileTransfer/WriteBytestream.h>
#include <Swiften/Network/Connection.h>

namespace Swift {
    class SOCKS5BytestreamRegistry;

    class SWIFTEN_API SOCKS5BytestreamServerSession {
        public:
        typedef std::shared_ptr<SOCKS5BytestreamServerSession> ref;

        public:
            enum State {
                Initial,
                WaitingForAuthentication,
                WaitingForRequest,
                ReadyForTransfer,
                ReadingData,
                WritingData,
                Finished
            };

            SOCKS5BytestreamServerSession(std::shared_ptr<Connection> connection, SOCKS5BytestreamRegistry* registry);
            ~SOCKS5BytestreamServerSession();

            void setChunkSize(int chunkSize) {
                this->chunkSize = chunkSize;
            }

            void start();
            void stop();

            void startSending(std::shared_ptr<ReadBytestream>);
            void startReceiving(std::shared_ptr<WriteBytestream>);

            HostAddressPort getAddressPort() const;

            boost::signals2::signal<void (boost::optional<FileTransferError>)> onFinished;
            boost::signals2::signal<void (unsigned long long)> onBytesSent;

            const std::string& getStreamID() const {
                return streamID;
            }

        private:
            void finish(const boost::optional<FileTransferError>& error = boost::optional<FileTransferError>());
            void process();
            void handleDataRead(std::shared_ptr<SafeByteArray>);
            void handleDisconnected(const boost::optional<Connection::Error>&);
            void handleDataAvailable();
            void sendData();

        private:
            std::shared_ptr<Connection> connection;
            SOCKS5BytestreamRegistry* bytestreams;
            ByteArray unprocessedData;
            State state;
            int chunkSize;
            std::string streamID;
            std::shared_ptr<ReadBytestream> readBytestream;
            std::shared_ptr<WriteBytestream> writeBytestream;
            bool waitingForData;

            boost::signals2::connection disconnectedConnection;
            boost::signals2::connection dataReadConnection;
            boost::signals2::connection dataWrittenConnection;
            boost::signals2::connection dataAvailableConnection;

    };
}