├── .github
└── workflows
│ └── c-cpp.yml
├── .gitignore
├── Makefile
├── README.md
├── driver.c
├── thread_socket.c
└── thread_socket.h
/.github/workflows/c-cpp.yml:
--------------------------------------------------------------------------------
1 | name: C/C++ CI
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 | pull_request:
7 | branches: [ "main" ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 | - name: make
17 | run: make
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | thread_socket
2 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -m64 -O3 -Wall -lpthread -fPIE -fstack-protector -Wno-incompatible-pointer-types
2 |
3 | thread_socket:
4 | clang $(CFLAGS) -o $(@) thread_socket.c driver.c
5 |
6 | clean:
7 | rm ./thread_socket
8 |
9 | install:
10 | cp -f ./thread_socket /usr/bin
11 |
12 | uninstall:
13 | rm -f /usr/bin/thread_socket
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 成品脚本
2 | [MLKit](https://github.com/sdk250/MLKit)
3 | # 介绍
4 | 这是一个`专门`用于百度直连的http轻量代理
5 | ~使用多线程编写,本身编译出来极为轻量~
6 | 更改程序执行逻辑,从 `多线程` 转至 `epoll多路复用` 。大幅度的降低了程序在高并发的情况下的内存占用
7 | 修改`用于连接的IP`在`thread_socket.h`中的宏定义`SERVER_ADDR`,将它修改为你想使用的百度直连IP,然后重新编译即可。
8 | 亦或者运行时加上 `-r` 参数来指定
9 | # Compile
10 | ```shell
11 | make
12 | ```
13 | If it is not working, please try:
14 | ```shell
15 | clang -m64 -O3 -Wall -lpthread -o thread_socket thread_socket.c driver.c
16 | ```
17 | # Usage
18 | ```shell
19 | ./thread_socket -h
20 | Usage of ./thread_socket:
21 | -p
22 | Set PORT while running
23 | -l Show running log
24 | -u
25 | Set UID while running
26 | -r
27 | Set IP of peer
28 | -d Start daemon service
29 | -h Show this message
30 | ```
31 | 编译以后可以在任意终端上运行,比如安卓的Termux
32 | 使用的最直接的使用方法就是运行后在手机的APN设置里面设置代理:
33 | 127.0.0.1 端口 默认为8080
34 | # Email
35 | ` hexfya@gmail.com `
36 |
37 |
--------------------------------------------------------------------------------
/driver.c:
--------------------------------------------------------------------------------
1 | #include "thread_socket.h"
2 |
3 | void signal_terminate(const int sign)
4 | {
5 | atomic_store_explicit(&SHUTDOWN, true, memory_order_release);
6 | fprintf(stderr, "Receive terminated signal: %d\n", sign);
7 | close(local_fd);
8 | }
9 |
10 | void usage(const char *argv, const int ret)
11 | {
12 | printf("Usage of %s:\n"
13 | "\t-p\t\n"
14 | "\t\tSet PORT while running\n"
15 | "\t-u\t\n"
16 | "\t\tSet UID while running\n"
17 | "\t-r\t\n"
18 | "\t\tSet IP of peer\n"
19 | "\t-l\tShow running log\n"
20 | "\t-d\tStart daemon service\n"
21 | "\t-h\tShow this message\n",
22 | argv
23 | );
24 | exit(ret);
25 | }
26 |
27 | void *handle_swap(void *arg)
28 | {
29 | int32_t epoll_fd = *(int32_t *) arg;
30 | char *buf = (char *) arg;
31 | memset(buf, '\0', sizeof(int32_t));
32 | struct epoll_event events[MAX_EVENT];
33 |
34 | for (int event_count = 0; !atomic_load_explicit(&SHUTDOWN, memory_order_relaxed);)
35 | {
36 | event_count = epoll_wait(epoll_fd, events, MAX_EVENT, -1);
37 | for (int i = 0; i < event_count; i++)
38 | {
39 | if (events[i].events & EPOLLIN)
40 | {
41 | int32_t *src = (int32_t *) &events[i].data.u64;
42 | int32_t *dst = src + 1;
43 | bool _continue = false;
44 |
45 | int recved = 0;
46 | for (;
47 | (recved = recv(*src, buf, SIZE, 0));
48 | )
49 | {
50 | if (recved < 0)
51 | {
52 | _continue = (errno == EAGAIN || errno == EWOULDBLOCK);
53 | break;
54 | }
55 | send(*dst, buf, recved, MSG_NOSIGNAL);
56 | memset(buf, '\0', recved);
57 | }
58 | if (!_continue || recved == 0)
59 | {
60 | for (int i = 0; i < 2; i++)
61 | {
62 | if (*(src + i) != 0)
63 | {
64 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, *(src + i), NULL);
65 | close(*(src + i));
66 | *(src + i) = 0;
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 | pthread_exit(NULL);
74 | return NULL;
75 | }
76 | void *handle_server(void *arg)
77 | {
78 | int32_t epoll_fd = *(int32_t *) arg;
79 | int32_t swap_epoll_fd = *(((int32_t *) arg) + 1);
80 | char *buf = (char *) arg;
81 | memset(buf, '\0', sizeof(int64_t));
82 | struct epoll_event event, events[MAX_EVENT];
83 |
84 | for (int event_count = 0; !atomic_load_explicit(&SHUTDOWN, memory_order_relaxed);)
85 | {
86 | event_count = epoll_wait(epoll_fd, events, MAX_EVENT, -1);
87 | for (int i = 0; i < event_count; i++)
88 | {
89 | struct server_argu *server_ptr = (struct server_argu *) events[i].data.ptr;
90 | int32_t src = server_ptr->src;
91 | int32_t dst = server_ptr->dst;
92 |
93 | if (events[i].events & EPOLLOUT)
94 | {
95 | send(
96 | dst,
97 | server_ptr->msg,
98 | strlen(server_ptr->msg),
99 | MSG_NOSIGNAL
100 | );
101 |
102 | memset(&event, '\0', sizeof(struct epoll_event));
103 | event.events = EPOLLIN | EPOLLET;
104 | event.data.ptr = events[i].data.ptr;
105 | events[i].data.ptr = NULL;
106 | epoll_ctl(epoll_fd, EPOLL_CTL_MOD, dst, &event);
107 |
108 | free(server_ptr->msg);
109 | server_ptr->msg = NULL;
110 | } else if (events[i].events & EPOLLIN) {
111 | for (
112 | short int i = 0, end_i = 39;
113 | (i = recv(dst, buf, end_i, 0)) != end_i && i > 0;
114 | end_i -= i
115 | ) continue;
116 | if (! strstr(buf, "\r\n\r\n"))
117 | {
118 | memset(buf, '\0', 39);
119 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, dst, NULL);
120 | shutdown(dst, SHUT_RDWR);
121 | close(dst);
122 | close(src);
123 | free(server_ptr);
124 | continue;
125 | }
126 |
127 | if (server_ptr->http_msg == NULL)
128 | send(
129 | src,
130 | buf,
131 | 39,
132 | MSG_NOSIGNAL
133 | );
134 | else {
135 | send(
136 | dst,
137 | server_ptr->http_msg,
138 | server_ptr->http_msg_len,
139 | MSG_NOSIGNAL
140 | );
141 | free(server_ptr->http_msg);
142 | server_ptr->http_msg = NULL;
143 | }
144 | memset(buf, '\0', 39);
145 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, dst, NULL);
146 | free(server_ptr);
147 | events[i].data.ptr = NULL;
148 |
149 | define_event(swap_epoll_fd, &event, src, dst);
150 | define_event(swap_epoll_fd, &event, dst, src);
151 | }
152 | }
153 | }
154 | pthread_exit(NULL);
155 | return NULL;
156 | }
157 | inline void define_event(
158 | int32_t epoll_fd,
159 | struct epoll_event *event,
160 | int32_t src,
161 | int32_t dst
162 | )
163 | {
164 | memset(event, '\0', sizeof(struct epoll_event));
165 | *(int32_t *) &(event->data) = src;
166 | *(((int32_t *) &(event->data)) + 1) = dst;
167 | event->events = EPOLLIN | EPOLLET;
168 | epoll_ctl(epoll_fd, EPOLL_CTL_ADD, src, event);
169 | }
170 | void main_loop(const int local_fd)
171 | {
172 | int epoll_fd, event_count;
173 | struct epoll_event event, events[MAX_EVENT];
174 | char *thread_buf_swap = calloc(SIZE, sizeof(char));
175 | char *thread_buf_server = calloc(SIZE, sizeof(char));
176 | char *buf = calloc(SIZE, sizeof(char));
177 | char *_buf = calloc(SIZE, sizeof(char));
178 | char *url = calloc(LEN_URL, sizeof(char));
179 | if (! thread_buf_swap || ! buf || ! _buf || ! thread_buf_server || ! url)
180 | {
181 | perror("calloc");
182 | exit(EXIT_FAILURE);
183 | }
184 |
185 | epoll_fd = epoll_create1(0);
186 | int32_t swap_epoll_fd = epoll_create1(0);
187 | int32_t server_epoll_fd = epoll_create1(0);
188 | *(int32_t *) thread_buf_swap = swap_epoll_fd;
189 | *(int32_t *) thread_buf_server = server_epoll_fd;
190 | *(((int32_t *) thread_buf_server) + 1) = swap_epoll_fd;
191 | pthread_t tid_swap, tid_server;
192 | pthread_create(&tid_swap, &attr, handle_swap, thread_buf_swap);
193 | pthread_create(&tid_server, &attr, handle_server, thread_buf_server);
194 |
195 | event.events = EPOLLIN;
196 | event.data.fd = local_fd;
197 | epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_fd, &event);
198 | for (; !atomic_load_explicit(&SHUTDOWN, memory_order_relaxed);)
199 | {
200 | event_count = epoll_wait(epoll_fd, events, MAX_EVENT, -1);
201 | for (int i = 0; i < event_count; i++)
202 | {
203 | int fd = events[i].data.fd;
204 | if (fd == local_fd)
205 | {
206 | int _fd = accept(fd, NULL, NULL);
207 | if (_fd < 0)
208 | continue;
209 |
210 | setNonBlocking(_fd);
211 | event.events = EPOLLIN | EPOLLET;
212 | event.data.fd = _fd;
213 | epoll_ctl(epoll_fd, EPOLL_CTL_ADD, _fd, &event);
214 | } else if (events[i].events & EPOLLIN) {
215 | int32_t total = 0, https = 0, dst = 0;
216 | struct sockaddr_in destination_addr;
217 | socklen_t len = sizeof(struct sockaddr);
218 |
219 | memset(&destination_addr, '\0', sizeof(struct sockaddr));
220 | if (getsockopt(
221 | fd,
222 | SOL_IP,
223 | SO_ORIGINAL_DST,
224 | &destination_addr,
225 | &len
226 | ) != 0 || (
227 | (ntohl(destination_addr.sin_addr.s_addr) == 0x0) || // 0.0.0.0/0
228 | (ntohl(destination_addr.sin_addr.s_addr) & 0xff000000) == 0x0a000000 || // 10.0.0.0/8
229 | (ntohl(destination_addr.sin_addr.s_addr) & 0xfff00000) == 0xac100000 || // 172.16.0.0/12
230 | (ntohl(destination_addr.sin_addr.s_addr) & 0xffff0000) == 0xc0a80000 || // 192.168.0.0/16
231 | (ntohl(destination_addr.sin_addr.s_addr) & 0xff000000) == 0x7f000000 || // 127.0.0.0/8
232 | (ntohl(destination_addr.sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000 || // 169.254.0.0/16
233 | (ntohl(destination_addr.sin_addr.s_addr) & 0xf0000000) == 0xe0000000 // 224.0.0.0/4
234 | )) {
235 | for (short int ret = 0;
236 | total + READ_SIZE < SIZE &&
237 | ! strstr(buf, "\r\n\r\n") &&
238 | (ret = recv(fd, buf + total, READ_SIZE, 0));
239 | )
240 | {
241 | if (ret == -1)
242 | break;
243 | else
244 | total += ret;
245 | }
246 |
247 | for (char *p = buf; (uintptr_t) p != 1 && p - buf < SIZE; p++)
248 | {
249 | if (sscanf(p, "Host: %" LEN_URL_STR "[^ \r\n]\r\n", url) == 1 ||
250 | sscanf(p, "host: %" LEN_URL_STR "[^ \r\n]\r\n", url) == 1
251 | )
252 | break;
253 |
254 | p = strchr(p, '\n');
255 | }
256 | if (*url == 0)
257 | {
258 | if (sscanf(buf, "CONNECT %" LEN_URL_STR "[^ ] %*[^ ]\r\n", url) != 1) {
259 | if (sscanf(buf, "GET %" LEN_URL_STR "[^ ] %*[^ ]\r\n", url) != 1) {
260 | if (sscanf(buf, "POST %" LEN_URL_STR "[^ ] %*[^ ]\r\n", url) != 1) {
261 | if (LOG) fprintf(stderr, "Unknown connection.\n");
262 | memset(buf, '\0', total);
263 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
264 | close(fd);
265 | continue;
266 | }
267 | }
268 | }
269 | }
270 | for (int i = 0; i < 8; i++)
271 | {
272 | if (buf[i] == "CONNECT "[i])
273 | https = 1;
274 | else {
275 | https = 0;
276 | break;
277 | }
278 | }
279 | if (!strchr(url, ':'))
280 | {
281 | if (https)
282 | strncat(url, ":443", LEN_URL);
283 | else
284 | strncat(url, ":80", LEN_URL);
285 | }
286 | } else {
287 | if (! inet_ntop(AF_INET, &destination_addr.sin_addr, url, INET_ADDRSTRLEN))
288 | {
289 | perror("Translation fail");
290 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
291 | close(fd);
292 | continue;
293 | }
294 | size_t len = strlen(url);
295 | if (len + 7 > LEN_URL)
296 | {
297 | fprintf(stderr, "URI is too long: %s\n", url);
298 | memset(url, '\0', len);
299 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
300 | close(fd);
301 | continue;
302 | }
303 | snprintf(
304 | url + len,
305 | LEN_URL,
306 | ":%u",
307 | ntohs(destination_addr.sin_port)
308 | );
309 | }
310 |
311 | if (LOG) printf("url: %s\n", url);
312 |
313 | if ((dst = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
314 | {
315 | perror("Create socket for zl");
316 | memset(buf, '\0', total);
317 | memset(url, '\0', strlen(url));
318 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
319 | close(fd);
320 | continue;
321 | }
322 | setNonBlocking(dst);
323 | set_socket_timeout(dst, 0, TIMEOUT);
324 |
325 | if (connect(
326 | dst,
327 | (struct sockaddr *) &server_addr,
328 | sizeof(struct sockaddr)) == -1 && errno != EINPROGRESS
329 | ) {
330 | perror("Connect to server fail");
331 | close(dst);
332 | memset(buf, '\0', total);
333 | memset(url, '\0', strlen(url));
334 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
335 | close(fd);
336 | continue;
337 | }
338 | snprintf(
339 | _buf,
340 | SIZE,
341 | "CONNECT %s HTTP/1.1\r\n\r\n",
342 | url
343 | );
344 | memset(&event, '\0', sizeof(struct epoll_event));
345 | event.events = EPOLLOUT | EPOLLET;
346 | event.data.ptr = calloc(1, sizeof(struct server_argu));
347 | if (event.data.ptr == NULL)
348 | {
349 | perror("calloc");
350 | close(dst);
351 | memset(buf, '\0', total);
352 | memset(_buf, '\0', strlen(_buf));
353 | memset(url, '\0', strlen(url));
354 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
355 | close(fd);
356 | continue;
357 | }
358 | ((struct server_argu *) event.data.ptr)->src = fd;
359 | ((struct server_argu *) event.data.ptr)->dst = dst;
360 | ((struct server_argu *) event.data.ptr)->msg = strdup(_buf);
361 | if (!https)
362 | {
363 | ((struct server_argu *) event.data.ptr)->http_msg = calloc(total + 1, sizeof(char));
364 | if (((struct server_argu *) event.data.ptr)->http_msg == NULL)
365 | {
366 | perror("calloc");
367 | close(dst);
368 | memset(buf, '\0', total);
369 | memset(_buf, '\0', strlen(_buf));
370 | memset(url, '\0', strlen(url));
371 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
372 | close(fd);
373 | continue;
374 | }
375 | memcpy(((struct server_argu *) event.data.ptr)->http_msg, buf, total);
376 | ((struct server_argu *) event.data.ptr)->http_msg_len = total;
377 | }
378 | epoll_ctl(server_epoll_fd, EPOLL_CTL_ADD, dst, &event);
379 |
380 | memset(buf, '\0', total);
381 | memset(_buf, '\0', strlen(_buf));
382 | memset(url, '\0', strlen(url));
383 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
384 | }
385 | }
386 | }
387 |
388 | close(epoll_fd);
389 | pthread_join(tid_swap, NULL);
390 | pthread_join(tid_server, NULL);
391 | close(swap_epoll_fd);
392 | close(server_epoll_fd);
393 | free(thread_buf_swap);
394 | free(thread_buf_server);
395 | free(buf);
396 | free(_buf);
397 | free(url);
398 | pthread_attr_destroy(&attr);
399 |
400 | puts("Main thread terminated.");
401 | }
402 |
403 | void set_socket_timeout(int fd, unsigned long int usec, unsigned int sec)
404 | {
405 | struct timeval tv = {
406 | .tv_usec = usec,
407 | .tv_sec = sec
408 | };
409 | setsockopt(
410 | fd,
411 | SOL_SOCKET,
412 | SO_SNDTIMEO,
413 | (void *) &tv,
414 | sizeof(struct timeval)
415 | );
416 | setsockopt(
417 | fd,
418 | SOL_SOCKET,
419 | SO_RCVTIMEO,
420 | (void *) &tv,
421 | sizeof(struct timeval)
422 | );
423 | }
424 | int setNonBlocking(int sockfd)
425 | {
426 | int flags = fcntl(sockfd, F_GETFL, 0);
427 | if (flags == -1) {
428 | perror("fcntl");
429 | return -1;
430 | }
431 |
432 | flags |= O_NONBLOCK;
433 | if (fcntl(sockfd, F_SETFL, flags) == -1) {
434 | perror("fcntl");
435 | return -1;
436 | }
437 |
438 | return 0;
439 | }
440 |
--------------------------------------------------------------------------------
/thread_socket.c:
--------------------------------------------------------------------------------
1 | #include "thread_socket.h"
2 |
3 | pthread_attr_t attr = {0};
4 | int LOG = 0;
5 | int local_fd = 0;
6 | struct sockaddr_in server_addr = {0};
7 | atomic_bool SHUTDOWN = false;
8 |
9 | int main(int argc, char **argv) {
10 | struct sockaddr_in local_addr = {0};
11 | int on = 1;
12 | int opt = 0;
13 | int daemon = 0;
14 | unsigned int port = 8080;
15 | pid_t pid = 0;
16 | pid_t sid = 0;
17 | char ip_s[16] = {0};
18 |
19 | if (argc == 1)
20 | usage(*argv, EXIT_FAILURE);
21 | for (;(opt = getopt(argc, argv, "p:u:r:dlh")) != -1;) {
22 | switch(opt) {
23 | case 'p':
24 | port = atoi(optarg);
25 | break;
26 | case 'd':
27 | daemon = 1;
28 | break;
29 | case 'l':
30 | LOG = 1;
31 | break;
32 | case 'u':
33 | if (setuid(atoi(optarg)))
34 | perror("Setuid error");
35 | break;
36 | case 'r':
37 | strncpy(ip_s, optarg, 15);
38 | break;
39 | case 'h':
40 | usage(*argv, EXIT_SUCCESS);
41 | break;
42 | case ':':
43 | printf("Missing argument after: -%c\n", optopt);
44 | usage(*argv, EXIT_FAILURE);
45 | break;
46 | case '?':
47 | printf("Invalid argument: -%c\n", optopt);
48 | usage(*argv, EXIT_FAILURE);
49 | default:
50 | usage(*argv, EXIT_FAILURE);
51 | }
52 | }
53 |
54 | if (*ip_s == '\0')
55 | strncpy(ip_s, SERVER_ADDR, 15);
56 |
57 | memset(&server_addr, '\0', sizeof(struct sockaddr));
58 | server_addr.sin_family = AF_INET;
59 | server_addr.sin_port = htons(443);
60 | if (inet_pton(AF_INET, ip_s, &server_addr.sin_addr) != 1)
61 | {
62 | perror("Translation address failed");
63 | exit(EXIT_FAILURE);
64 | }
65 |
66 | signal(SIGPIPE, SIG_IGN);
67 | signal(SIGALRM, SIG_IGN);
68 | signal(SIGINT, signal_terminate);
69 | signal(SIGTERM, signal_terminate);
70 | if ((local_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
71 | perror("Create local server socket file descriptor fail");
72 | close(local_fd);
73 | exit(EXIT_FAILURE);
74 | }
75 | setsockopt(local_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
76 | memset(&local_addr, '\0', sizeof(struct sockaddr));
77 | local_addr.sin_family = AF_INET;
78 | local_addr.sin_port = htons(port);
79 | local_addr.sin_addr.s_addr = INADDR_ANY;
80 | if (bind(
81 | local_fd,
82 | (const struct sockaddr *) &local_addr,
83 | sizeof(struct sockaddr)
84 | ) < 0) {
85 | fprintf(
86 | stderr,
87 | "Bind %s:%u error",
88 | inet_ntoa(local_addr.sin_addr),
89 | port
90 | );
91 | perror(" ");
92 | close(local_fd);
93 | exit(EXIT_FAILURE);
94 | }
95 | if (listen(local_fd, 50) < 0) {
96 | perror("listen");
97 | close(local_fd);
98 | exit(EXIT_FAILURE);
99 | }
100 | setNonBlocking(local_fd);
101 | printf(
102 | __TIME__ "\t" __DATE__ "\n"
103 | "Listen on %s:%u.\n",
104 | inet_ntoa(local_addr.sin_addr),
105 | port
106 | );
107 | pthread_attr_init(&attr);
108 | pthread_attr_setstacksize(&attr, 512 * 1024);
109 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
110 | if (daemon) {
111 | if ((pid = fork()) == 0) {
112 | if ((sid = setsid()) < 0) {
113 | perror("setsid error");
114 | exit(EXIT_FAILURE);
115 | }
116 | close(STDIN_FILENO);
117 | close(STDOUT_FILENO);
118 | // close(STDERR_FILENO);
119 | main_loop(local_fd);
120 | } else {
121 | printf("The PID of %s is %d.\n", *argv, pid);
122 | close(local_fd);
123 | }
124 | } else
125 | main_loop(local_fd);
126 |
127 | return 0;
128 | }
129 |
--------------------------------------------------------------------------------
/thread_socket.h:
--------------------------------------------------------------------------------
1 | #ifndef __THREAD_SOCKET__
2 | #define __THREAD_SOCKET__
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #define SIZE 0x80000
20 | #define LEN_URL (SIZE / 2)
21 | #define LEN_URL_STR "262143" // LEN_URL - 1
22 | #define U_TIMEOUT 500000
23 | #define TIMEOUT 3
24 | #define SERVER_ADDR "110.242.70.68"
25 | #define READ_SIZE 0x100
26 | #define MAX_EVENT (64)
27 |
28 | extern pthread_attr_t attr;
29 | extern int LOG;
30 | extern int local_fd;
31 | extern struct sockaddr_in server_addr;
32 | extern atomic_bool SHUTDOWN;
33 |
34 | struct server_argu
35 | {
36 | int32_t src;
37 | int32_t dst;
38 | char *msg;
39 | char *http_msg;
40 | uint32_t http_msg_len;
41 | };
42 |
43 | int setNonBlocking(int);
44 | void set_socket_timeout(int, unsigned long int, unsigned int);
45 | void *swap_data(void *);
46 | void main_loop(int);
47 | void usage(const char *, int);
48 | void signal_terminate(int);
49 | void *handle_server(void *);
50 | void *handle_swap(void *);
51 | extern inline void define_event(
52 | int32_t epoll_fd,
53 | struct epoll_event *event,
54 | int32_t src,
55 | int32_t dst
56 | );
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------