forked from TunSafe/TunSafe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
service_pipe_win32.h
111 lines (90 loc) · 2.66 KB
/
service_pipe_win32.h
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-License-Identifier: AGPL-1.0-only
// Copyright (C) 2018 Ludvig Strigeus <[email protected]>. All Rights Reserved.
#pragma once
#include "tunsafe_threading.h"
#include "network_win32_api.h"
class PipeManager;
// Once a pipe connects, this object is used to facilitate the connection
class PipeConnection {
friend class PipeManager;
public:
class Delegate {
public:
virtual bool HandleMessage(int type, uint8 *data, size_t size) = 0;
virtual void HandleDisconnect() = 0;
};
PipeConnection();
~PipeConnection();
void Configure(PipeManager *manager, int slot);
bool WritePacket(int type, const uint8 *data, size_t data_size);
HANDLE pipe_handle() { return pipe_; }
bool is_connected() { return connection_established_; }
bool VerifyThread();
private:
// -1 = fail, 0 = wait, 1 = conn
int InitializeServerPipeAndConnect();
bool InitializeClientPipe();
void AdvanceStateMachine();
void ClosePipe();
void TrySendNextQueuedWrite();
void HandleWriteComplete();
Delegate *delegate_;
PipeManager *manager_;
HANDLE pipe_;
bool write_overlapped_active_;
bool connection_established_;
enum State {
kStateNone,
kStateStarting,
kStateWaitConnect,
kStateWaitReadLength,
kStateWaitReadPayload,
kStateWaitTimeout,
};
uint8 state_;
uint32 packet_size_;
struct OutgoingPacket {
OutgoingPacket *next;
uint32 size;
uint8 data[0];
};
OutgoingPacket *packets_, **packets_end_;
uint8 *tmp_packet_buf_;
DWORD tmp_packet_size_;
DWORD read_pos_;
OVERLAPPED write_overlapped_, read_overlapped_;
Mutex packets_mutex_;
};
// This class supports multiple PipeConnections and calls HandleNewConnection
// when a new pipe connection is established.
class PipeManager {
friend class PipeConnection;
public:
class Delegate {
public:
// Called when a new connection is established
virtual PipeConnection::Delegate *HandleNewConnection(PipeConnection *handler) = 0;
// Called when a notification event was pushed
virtual void HandleNotify() = 0;
};
PipeManager(const char *pipe_name, bool is_server_pipe, Delegate *delegate);
~PipeManager();
bool StartThread();
void StopThread();
bool VerifyThread();
HANDLE notify_handle() { return events_[0]; }
PipeConnection *GetClientConnection() { return &connections_[0]; }
void TryStartNewListener();
private:
DWORD ThreadMain();
static DWORD WINAPI StaticThreadMain(void *x);
Delegate *delegate_;
HANDLE thread_;
char *pipe_name_;
DWORD thread_id_;
bool is_server_pipe_;
bool exit_thread_;
enum { kMaxConnections = 2 };
HANDLE events_[1 + kMaxConnections * 2];
PipeConnection connections_[kMaxConnections];
};