root/lang/c/partty/trunk/partty.h @ 7180

Revision 7180, 8.0 kB (checked in by frsyuki, 6 years ago)

lang/c/partty: fixed busy loop probrem

Line 
1#ifndef PARTTY_H__
2#define PARTTY_H__ 1
3
4#ifdef HAVE_CONFIG_H
5#include "config.h"
6#endif
7
8#include <stddef.h>
9#include <stdint.h>
10#include <stdexcept>
11#include <cstring>
12
13#ifndef PARTTY_GATE_DIR
14#define PARTTY_GATE_DIR "./var/socket/"
15#endif
16
17#ifndef PARTTY_ARCHIVE_DIR
18#define PARTTY_ARCHIVE_DIR \
19        "./archive/archive/"
20#endif
21
22#ifndef PARTTY_GATE_SESSION_BANNER
23#define PARTTY_GATE_SESSION_BANNER \
24        "Welcome to Partty hogehoge!\r\n\r\nSession name: "
25#endif
26
27#ifndef PARTTY_GATE_PASSWORD_BANNER
28#define PARTTY_GATE_PASSWORD_BANNER \
29        "Password: "
30#endif
31
32#ifndef PARTTY_SERVER_WELCOME_MESSAGE
33#define PARTTY_SERVER_WELCOME_MESSAGE \
34        "\r\n>Partty! connected.\r\n"
35#endif
36
37#ifndef PARTTY_SESSION_START_MESSAGE
38#define PARTTY_SESSION_START_MESSAGE \
39        ">Partty! start\r\n"
40#endif
41
42#ifndef PARTTY_SESSION_END_MESSAGE
43#define PARTTY_SESSION_END_MESSAGE \
44        ">Partty! end"
45#endif
46
47
48#define PARTTY_RAW_GATE_FLASH_CROSS_DOMAIN_SUPPORT
49#ifndef PARTTY_RAW_GATE_FLASH_CROSS_DOMAIN_POLICY
50#define PARTTY_RAW_GATE_FLASH_CROSS_DOMAIN_POLICY \
51        "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>"
52#endif
53
54
55namespace Partty {
56
57
58static const unsigned short SERVER_DEFAULT_PORT   = 2750;
59static const unsigned short GATE_DEFAULT_PORT     = 7777;
60
61static const size_t MAX_SESSION_NAME_LENGTH = 128;
62static const size_t MIN_SESSION_NAME_LENGTH = 3;
63static const size_t MAX_PASSWORD_LENGTH     = 128;
64static const size_t MAX_USER_NAME_LENGTH    = 128;
65
66
67static const char* const GATE_DIR = PARTTY_GATE_DIR;
68static const char* const ARCHIVE_DIR = PARTTY_ARCHIVE_DIR;
69static const char* const GATE_PASSWORD_BANNER = PARTTY_GATE_PASSWORD_BANNER;
70static const char* const GATE_SESSION_BANNER = PARTTY_GATE_SESSION_BANNER;
71static const char* const SERVER_WELCOME_MESSAGE = PARTTY_SERVER_WELCOME_MESSAGE;
72static const char* const SESSION_START_MESSAGE = PARTTY_SESSION_START_MESSAGE;
73static const char* const SESSION_END_MESSAGE = PARTTY_SESSION_END_MESSAGE;
74
75
76static const uint8_t PROTOCOL_VERSION = 1;
77
78static const char   NEGOTIATION_MAGIC_STRING[] = "Partty!";
79static const size_t NEGOTIATION_MAGIC_STRING_LENGTH = 7;
80
81struct negotiation_header_t {
82        char magic[NEGOTIATION_MAGIC_STRING_LENGTH];  // "Partty!"
83        uint8_t protocol_version;
84        uint16_t user_name_length;
85        uint16_t session_name_length;
86        uint16_t writable_password_length;
87        uint16_t readonly_password_length;
88        // char user_name[user_name_length];
89        // char session_name[session_name_length];
90        // char writable_password[writable_password_length];
91        // char readonly_password[readonly_password_length];
92};
93
94namespace negotiation_reply {
95        static const uint16_t SUCCESS = 0;
96        static const uint16_t PROTOCOL_MISMATCH = 1;
97        static const uint16_t SESSION_UNAVAILABLE = 2;
98        static const uint16_t SERVER_ERROR = 3;
99        static const uint16_t AUTHENTICATION_FAILED = 4;
100};
101struct negotiation_reply_t {
102        uint16_t code;
103        uint16_t message_length;
104        // char message[message_length];
105};
106
107
108struct partty_error : public std::runtime_error {
109        partty_error(const std::string& message) : runtime_error(message) {}
110        virtual ~partty_error() throw() {}
111};
112
113struct initialize_error : public partty_error {
114        initialize_error(const std::string& message) : partty_error(message) {}
115        virtual ~initialize_error() throw() {}
116};
117
118struct io_error : public partty_error {
119        io_error(const std::string& message) : partty_error(message) {}
120        virtual ~io_error() throw() {}
121};
122
123struct io_end_error : public io_error {
124        io_end_error(const std::string& message) : io_error(message) {}
125        virtual ~io_end_error() throw() {}
126};
127
128
129struct session_info_t;
130struct session_info_ref_t {
131        inline session_info_ref_t(const session_info_t& src);
132        session_info_ref_t() {}
133        uint16_t user_name_length;
134        uint16_t session_name_length;
135        uint16_t readonly_password_length;
136        uint16_t writable_password_length;
137        const char* user_name;
138        const char* session_name;
139        const char* readonly_password;
140        const char* writable_password;
141};
142
143struct session_info_t {
144        inline session_info_t(const session_info_ref_t& ref);
145        session_info_t() {}
146        uint16_t user_name_length;
147        uint16_t session_name_length;
148        uint16_t writable_password_length;
149        uint16_t readonly_password_length;
150        char user_name[MAX_USER_NAME_LENGTH];
151        char session_name[MAX_SESSION_NAME_LENGTH];
152        char writable_password[MAX_PASSWORD_LENGTH];
153        char readonly_password[MAX_PASSWORD_LENGTH];
154};
155
156session_info_ref_t::session_info_ref_t(const session_info_t& src) :
157        user_name_length         (src.user_name_length        ),
158        session_name_length      (src.session_name_length     ),
159        readonly_password_length (src.readonly_password_length),
160        writable_password_length (src.writable_password_length),
161        user_name                (src.user_name               ),
162        session_name             (src.session_name            ),
163        readonly_password        (src.readonly_password       ),
164        writable_password        (src.writable_password       ) {}
165
166session_info_t::session_info_t(const session_info_ref_t& ref) :
167        session_name_length      (ref.session_name_length     ),
168        writable_password_length (ref.writable_password_length),
169        readonly_password_length (ref.readonly_password_length)
170{
171        if( user_name_length > MAX_USER_NAME_LENGTH ) {
172                throw initialize_error("user name is too long");
173        }
174        if( session_name_length > MAX_SESSION_NAME_LENGTH ) {
175                throw initialize_error("session name is too long");
176        }
177        if( session_name_length < MIN_SESSION_NAME_LENGTH ) {
178                throw initialize_error("session name is too short");
179        }
180        if( writable_password_length > MAX_PASSWORD_LENGTH ) {
181                throw initialize_error("operation password is too long");
182        }
183        if( readonly_password_length > MAX_PASSWORD_LENGTH ) {
184                throw initialize_error("view-only password is too long");
185        }
186        std::memcpy(user_name,         ref.user_name,         ref.user_name_length);
187        std::memcpy(session_name,      ref.session_name,      ref.session_name_length);
188        std::memcpy(writable_password, ref.writable_password, ref.writable_password_length);
189        std::memcpy(readonly_password, ref.readonly_password, ref.readonly_password_length);
190}
191
192
193template <size_t Length>
194struct line_t {
195        char str[Length];
196        size_t len;
197};
198struct gate_message_t {
199        line_t<MAX_SESSION_NAME_LENGTH> session_name;
200        line_t<MAX_PASSWORD_LENGTH> password;
201};
202
203
204// Hostを待ち受け、Multiplexerをforkする
205class ServerIMPL;
206class Server {
207public:
208        Server(int listen_socket);
209        ~Server();
210        int run(void);
211private:
212        ServerIMPL* impl;
213        Server();
214        Server(const Server&);
215};
216
217
218// Hostからの入力をゲストにコピーする
219// ゲストからの入力をHostにコピーする
220class MultiplexerIMPL;
221class Multiplexer {
222public:
223        Multiplexer(int host_socket, int gate_socket,
224                const session_info_ref_t& info);
225        ~Multiplexer();
226        int run(void);
227private:
228        MultiplexerIMPL* impl;
229        Multiplexer();
230        Multiplexer(const Multiplexer&);
231};
232
233
234// 新しい仮想端末を確保して、シェルを起動する
235// 標準入力とServerからの入力をシェルにコピーする
236// シェルの出力と標準出力をServerにコピーする
237class HostIMPL;
238class Host {
239public:
240        struct config_t {
241                config_t(int _server_socket,
242                                const session_info_ref_t& info_) :
243                        server_socket(_server_socket),
244                        info(info_) {}
245        public:
246                int lock_code;
247        private:
248                int server_socket;
249                const session_info_ref_t& info;
250                friend class HostIMPL;
251        };
252public:
253        Host(int server_socket, char lock_code,
254                const session_info_ref_t& info);
255        ~Host();
256        int run(void);
257private:
258        HostIMPL* impl;
259        Host();
260        Host(const Host&);
261};
262
263
264// ゲストを待ち受け、ファイルディスクリプタを
265// Hostに転送する
266class GateIMPL;
267class Gate {
268public:
269        struct config_t {
270                config_t(int listen_socket_) :
271                        listen_socket(listen_socket_) {}
272        public:
273        private:
274                int listen_socket;
275                friend class GateIMPL;
276        };
277public:
278        Gate(int listen_socket);
279        ~Gate();
280        int run(void);
281        void signal_end(void);
282private:
283        GateIMPL* impl;
284        Gate();
285        Gate(const Gate&);
286};
287
288
289// プロトコルにTelnetではなくRawストリームを
290// 使うGate
291class RawGateIMPL;
292class RawGate {
293public:
294        RawGate(int listen_socket);
295        ~RawGate();
296        int run(void);
297        void signal_end(void);
298private:
299        RawGateIMPL* impl;
300        RawGate();
301        RawGate(const RawGate&);
302};
303
304
305}  // namespace Partty
306
307#endif /* partty.h */
308
Note: See TracBrowser for help on using the browser.