-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunix_evilsocket.cc
133 lines (110 loc) · 3.26 KB
/
unix_evilsocket.cc
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "evilsocket.h"
#include <memory>
errno_t es_init() { return 0; }
void es_deinit() { }
errno_t es_last_error() {
return errno;
}
std::string es_error_message(errno_t error_code) {
char* s = strerror(error_code);
std::string string(s);
return s;
}
socket_t es_connect(const std::string& host, int port, int keepalivesec) {
socket_t handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (handle == INVALID_SOCKET) {
return INVALID_SOCKET;
}
address_t serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(host.c_str());
serverAddress.sin_port = htons(port);
auto res = connect(handle, reinterpret_cast<sockaddr*>(&serverAddress), sizeof(serverAddress));
if (res == 0)
return handle;
int on = 1;
int secs = keepalivesec;
setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
setsockopt(handle, IPPROTO_TCP, TCP_KEEPALIVE, &secs, sizeof(secs));
return INVALID_SOCKET;
}
void es_close(socket_t handle) {
if (handle != INVALID_SOCKET)
close(handle);
}
size_t es_write_string(socket_t handle, const std::string& string) {
if (handle == INVALID_SOCKET) {
errno = ERROR_INVALID_HANDLE;
return 0;
}
if (string.length() == 0) {
errno = 0;
return 0;
}
auto res = send(handle, string.c_str(), string.length(), 0);
if (res == -1) {
return 0;
}
return res;
}
std::string es_recv_string(socket_t handle, int limit) {
if (handle == INVALID_SOCKET) {
errno = ERROR_INVALID_HANDLE;
return std::string();
}
auto buffer = std::make_unique<char[]>(limit + 1);
buffer[limit] = 0;
auto res = recv(handle, buffer.get(), limit, 0);
if (res == -1) {
return std::string();
}
auto string = std::string(buffer.get());
return std::move(string);
}
std::string es_recv_string(socket_t handle, char terminator) {
if (handle == INVALID_SOCKET) {
errno = ERROR_INVALID_HANDLE;
return std::string();
}
char buffer = 0;
std::string string;
do {
auto res = recv(handle, &buffer, 1, 0);
if (res == -1) {
break;
}
if (buffer != terminator)
string += buffer;
} while (buffer != terminator);
return std::move(string);
}
socket_t es_listen(int port, int backlog) {
socket_t handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (handle == INVALID_SOCKET) {
return INVALID_SOCKET;
}
address_t serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(port);
auto res = bind(handle, reinterpret_cast<sockaddr*>(&serverAddress), sizeof(serverAddress));
if (res == -1) {
return INVALID_SOCKET;
}
listen(handle, backlog);
return handle;
}
std::pair<address_t, socket_t> es_accept(socket_t handle, int keepalivesec, bool wait) {
address_t clientAddress{};
socklen_t len = sizeof(clientAddress);
if (handle == INVALID_SOCKET) {
errno = ERROR_INVALID_HANDLE;
return { clientAddress, INVALID_SOCKET };
}
auto clientHandle = accept(handle, reinterpret_cast<sockaddr*>(&clientAddress), &len);
int on = 1;
int secs = keepalivesec;
setsockopt(clientHandle, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
setsockopt(clientHandle, IPPROTO_TCP, TCP_KEEPALIVE, &secs, sizeof(secs));
return { clientAddress, clientHandle };
}