-
Notifications
You must be signed in to change notification settings - Fork 0
/
server_lin.cpp
112 lines (89 loc) · 1.86 KB
/
server_lin.cpp
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
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <iostream>
#include "berasn1.hpp"
#include "xtypes.hpp"
#define BUFFER_SIZE 0x1000
byte buf[BUFFER_SIZE];
void
sigchld_handler(
int s)
{
MAKEUSED(s);
// waitpid() might overwrite errno, so we save and restore it:
int saved_errno = errno;
while (waitpid(-1, NULL, WNOHANG) > 0)
{
}
errno = saved_errno;
}
int
main(void)
{
std::cout << "Server started" << std::endl;
struct berasn1_conn conn;
int res;
struct sigaction sa;
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, 0) == -1)
{
perror("sigaction");
exit(EXIT_FAILURE);
}
res = berasn1_bind_listen(&conn, (char*)"1234");
if (res)
{
fprintf(stderr, "Failed to bind, stop\xa");
exit(EXIT_FAILURE);
}
while (1)
{
struct berasn1_conn newconn;
res = berasn1_accept(&newconn, &conn);
// NOTE(toideng): This approach is a humongous security hole and
// can easily be used to perform a variety of DOS
// attacks. But this is good enough for a test
// code
if (!fork())
{
berasn1_close(&conn);
while (1)
{
ssize_t res;
res = berasn1_recv(&newconn, buf, BUFFER_SIZE);
if (!res)
break;
if (res < 0)
{
berasn1_close(&newconn);
exit(EXIT_FAILURE);
}
if (newconn.is_receiving)
{
// Incoming message too large to handle
berasn1_close(&newconn);
exit(EXIT_FAILURE);
}
res = berasn1_send(&newconn, buf, (size_t)res);
if (!res)
break;
if (res < 0)
{
berasn1_close(&newconn);
exit(EXIT_FAILURE);
}
}
berasn1_close(&newconn);
exit(EXIT_SUCCESS);
}
berasn1_close(&newconn);
}
berasn1_close(&conn);
return 0;
}