Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
bytevia
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Michael Pastushkov
bytevia
Commits
ee99ee5a
Commit
ee99ee5a
authored
Sep 18, 2024
by
michaelpastushkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup formatting
parent
86fa807c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
194 additions
and
116 deletions
+194
-116
src/bytevia.c
+194
-116
No files found.
src/bytevia.c
View file @
ee99ee5a
...
...
@@ -68,7 +68,8 @@ unsigned char cipher[256];
int
cipher_time
;
struct
client_info
clients
[
MAX_UDP_CLIENTS
];
char
*
get_current_timestamp
(
void
)
{
char
*
get_current_timestamp
(
void
)
{
static
char
date_str
[
20
];
time_t
date
;
time
(
&
date
);
...
...
@@ -76,7 +77,8 @@ char *get_current_timestamp(void) {
return
date_str
;
}
unsigned
int
xorshift32
(
unsigned
int
*
state
)
{
unsigned
int
xorshift32
(
unsigned
int
*
state
)
{
unsigned
int
x
=
*
state
;
x
^=
x
<<
13
;
x
^=
x
>>
17
;
...
...
@@ -85,10 +87,12 @@ unsigned int xorshift32(unsigned int *state) {
return
x
;
}
void
shuffle
(
unsigned
char
*
array
,
int
n
,
unsigned
int
seed
)
{
void
shuffle
(
unsigned
char
*
array
,
int
n
,
unsigned
int
seed
)
{
unsigned
int
state
=
seed
;
srand
(
seed
);
for
(
int
i
=
n
-
1
;
i
>
0
;
i
--
)
{
for
(
int
i
=
n
-
1
;
i
>
0
;
i
--
)
{
int
j
=
xorshift32
(
&
state
)
%
(
i
+
1
);
int
temp
=
array
[
i
];
array
[
i
]
=
array
[
j
];
...
...
@@ -96,7 +100,8 @@ void shuffle(unsigned char *array, int n, unsigned int seed) {
}
}
unsigned
int
get_hash
(
unsigned
int
source
)
{
unsigned
int
get_hash
(
unsigned
int
source
)
{
unsigned
int
hash
=
source
;
hash
=
(
hash
^
61
)
^
(
hash
>>
16
);
hash
=
hash
+
(
hash
<<
3
);
...
...
@@ -112,7 +117,8 @@ int get_time()
return
now
/
(
60
*
10
);
/* changing cipher every 10 minutes */
}
void
update_cipher
()
{
void
update_cipher
()
{
int
i
;
unsigned
int
seed
;
...
...
@@ -127,10 +133,13 @@ void update_cipher() {
shuffle
(
cipher
,
sizeof
(
cipher
),
seed
);
if
(
options
.
log
>
1
)
{
if
(
options
.
log
>
1
)
{
printf
(
"%s new cipher %i
\n
"
,
get_current_timestamp
(),
time
);
if
(
options
.
log
>
2
)
{
for
(
i
=
0
;
i
<
256
;
i
++
)
{
if
(
options
.
log
>
2
)
{
for
(
i
=
0
;
i
<
256
;
i
++
)
{
printf
(
"%d "
,
cipher
[
i
]);
if
((
i
+
1
)
%
16
==
0
)
printf
(
"
\n
"
);
...
...
@@ -140,14 +149,16 @@ void update_cipher() {
cipher_time
=
time
;
}
int
encode
(
unsigned
char
*
buf
,
int
len
)
{
int
encode
(
unsigned
char
*
buf
,
int
len
)
{
int
i
;
if
(
!
options
.
encrypt
)
return
0
;
update_cipher
();
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
buf
[
i
]
=
cipher
[
buf
[
i
]];
if
(
options
.
log
)
{
if
(
options
.
log
)
{
printf
(
"
\r
%-50s"
,
" "
);
printf
(
"
\r
%s encode %i bytes "
,
get_current_timestamp
(),
len
);
fflush
(
stdout
);
...
...
@@ -155,20 +166,25 @@ int encode(unsigned char* buf, int len) {
return
0
;
}
int
decode
(
unsigned
char
*
buf
,
int
len
)
{
int
decode
(
unsigned
char
*
buf
,
int
len
)
{
int
i
,
j
;
if
(
!
options
.
encrypt
)
return
0
;
update_cipher
();
for
(
i
=
0
;
i
<
len
;
i
++
)
{
for
(
j
=
0
;
j
<
256
;
j
++
)
{
if
(
cipher
[
j
]
==
buf
[
i
])
{
for
(
i
=
0
;
i
<
len
;
i
++
)
{
for
(
j
=
0
;
j
<
256
;
j
++
)
{
if
(
cipher
[
j
]
==
buf
[
i
])
{
buf
[
i
]
=
j
;
break
;
}
}
}
if
(
options
.
log
)
{
if
(
options
.
log
)
{
printf
(
"
\r
%-50s"
,
" "
);
printf
(
"
\r
%s decode %i bytes "
,
get_current_timestamp
(),
len
);
fflush
(
stdout
);
...
...
@@ -176,11 +192,13 @@ int decode(unsigned char* buf, int len) {
return
0
;
}
int
build_udp
(
void
)
{
int
build_udp
(
void
)
{
/* Create local socket */
rc
.
client_socket
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
if
((
rc
.
client_socket
)
<
0
)
{
if
((
rc
.
client_socket
)
<
0
)
{
perror
(
"build_udp: local socket()"
);
return
1
;
}
...
...
@@ -190,14 +208,16 @@ int build_udp(void) {
rc
.
client_addr
.
sin_addr
.
s_addr
=
inet_addr
(
options
.
bind_address
);
rc
.
client_addr
.
sin_port
=
htons
(
options
.
local_port
);
if
(
bind
(
rc
.
client_socket
,
(
struct
sockaddr
*
)
&
rc
.
client_addr
,
sizeof
(
rc
.
client_addr
))
<
0
)
{
if
(
bind
(
rc
.
client_socket
,
(
struct
sockaddr
*
)
&
rc
.
client_addr
,
sizeof
(
rc
.
client_addr
))
<
0
)
{
perror
(
"build_udp: bind()"
);
return
1
;
}
return
0
;
}
int
build_tcp
(
void
)
{
int
build_tcp
(
void
)
{
memset
(
&
rc
.
server_addr
,
0
,
sizeof
(
rc
.
server_addr
));
...
...
@@ -206,14 +226,15 @@ int build_tcp(void) {
rc
.
server_addr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
rc
.
server_socket
=
socket
(
AF_INET
,
options
.
proto
,
0
);
if
(
rc
.
server_socket
<
0
)
{
if
(
rc
.
server_socket
<
0
)
{
perror
(
"build_tcp: socket()"
);
return
1
;
}
int
optval
=
1
;
#ifdef __MINGW32__
if
(
setsockopt
(
rc
.
server_socket
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
const
char
*
)
&
optval
,
sizeof
(
optval
))
<
0
)
if
(
setsockopt
(
rc
.
server_socket
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
const
char
*
)
&
optval
,
sizeof
(
optval
))
<
0
)
#else
if
(
setsockopt
(
rc
.
server_socket
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
optval
,
sizeof
(
optval
))
<
0
)
#endif
...
...
@@ -222,16 +243,19 @@ int build_tcp(void) {
return
1
;
}
if
(
options
.
bind_address
)
{
if
(
options
.
bind_address
)
{
rc
.
server_addr
.
sin_addr
.
s_addr
=
inet_addr
(
options
.
bind_address
);
}
if
(
bind
(
rc
.
server_socket
,
(
struct
sockaddr
*
)
&
rc
.
server_addr
,
sizeof
(
rc
.
server_addr
))
<
0
)
{
if
(
bind
(
rc
.
server_socket
,
(
struct
sockaddr
*
)
&
rc
.
server_addr
,
sizeof
(
rc
.
server_addr
))
<
0
)
{
perror
(
"build_server: bind()"
);
return
1
;
}
if
(
listen
(
rc
.
server_socket
,
1
)
<
0
)
{
if
(
listen
(
rc
.
server_socket
,
1
)
<
0
)
{
perror
(
"build_server: listen()"
);
return
1
;
}
...
...
@@ -239,7 +263,8 @@ int build_tcp(void) {
return
0
;
}
int
wait_connection
(
void
)
{
int
wait_connection
(
void
)
{
#if defined(__MINGW32__)
int
client_addr_size
;
...
...
@@ -248,17 +273,22 @@ int wait_connection(void) {
#endif
client_addr_size
=
sizeof
(
struct
sockaddr_in
);
if
(
options
.
proto
==
SOCK_DGRAM
)
{
if
(
options
.
proto
==
SOCK_DGRAM
)
{
char
buf
[
BUFFER_SIZE
];
int
bytes
=
recvfrom
(
rc
.
client_socket
,
buf
,
sizeof
(
buf
),
MSG_PEEK
,
(
struct
sockaddr
*
)
&
rc
.
client_addr
,
&
client_addr_size
);
if
(
bytes
<
0
)
{
if
(
bytes
<
0
)
{
if
(
errno
!=
EINTR
)
perror
(
"wait_connection: recvfrom(PEEK)"
);
return
1
;
}
}
else
{
rc
.
client_socket
=
accept
(
rc
.
server_socket
,
(
struct
sockaddr
*
)
&
rc
.
client_addr
,
&
client_addr_size
);
if
(
rc
.
client_socket
<
0
)
{
}
else
{
rc
.
client_socket
=
accept
(
rc
.
server_socket
,
(
struct
sockaddr
*
)
&
rc
.
client_addr
,
&
client_addr_size
);
if
(
rc
.
client_socket
<
0
)
{
if
(
errno
!=
EINTR
)
perror
(
"wait_connection: accept()"
);
return
1
;
...
...
@@ -267,7 +297,8 @@ int wait_connection(void) {
printf
(
"%s request from %s
\n
"
,
get_current_timestamp
(),
inet_ntoa
(
rc
.
client_addr
.
sin_addr
));
}
if
(
options
.
client_address
&&
(
strcmp
(
inet_ntoa
(
rc
.
client_addr
.
sin_addr
),
options
.
client_address
)
!=
0
))
{
if
(
options
.
client_address
&&
(
strcmp
(
inet_ntoa
(
rc
.
client_addr
.
sin_addr
),
options
.
client_address
)
!=
0
))
{
if
(
options
.
log
)
printf
(
"%s refused request from %s
\n
"
,
get_current_timestamp
(),
inet_ntoa
(
rc
.
client_addr
.
sin_addr
));
close
(
rc
.
client_socket
);
...
...
@@ -277,9 +308,11 @@ int wait_connection(void) {
return
0
;
}
int
build
()
{
int
build
()
{
rc
.
remote_host
=
gethostbyname
(
options
.
remote_host
);
if
(
rc
.
remote_host
==
NULL
)
{
if
(
rc
.
remote_host
==
NULL
)
{
perror
(
"build: gethostbyname()"
);
return
1
;
}
...
...
@@ -290,13 +323,16 @@ int build() {
memcpy
(
&
rc
.
remote_addr
.
sin_addr
.
s_addr
,
rc
.
remote_host
->
h_addr
,
rc
.
remote_host
->
h_length
);
rc
.
remote_socket
=
socket
(
AF_INET
,
options
.
proto
,
0
);
if
(
rc
.
remote_socket
<
0
)
{
if
(
rc
.
remote_socket
<
0
)
{
perror
(
"build: socket()"
);
return
1
;
}
if
(
options
.
proto
==
SOCK_STREAM
)
{
if
(
connect
(
rc
.
remote_socket
,
(
struct
sockaddr
*
)
&
rc
.
remote_addr
,
sizeof
(
rc
.
remote_addr
))
<
0
)
{
if
(
options
.
proto
==
SOCK_STREAM
)
{
if
(
connect
(
rc
.
remote_socket
,
(
struct
sockaddr
*
)
&
rc
.
remote_addr
,
sizeof
(
rc
.
remote_addr
))
<
0
)
{
perror
(
"build: connect()"
);
return
1
;
}
...
...
@@ -304,10 +340,13 @@ int build() {
return
0
;
}
int
add_udp_client
(
struct
sockaddr_in
client_addr
,
pid_t
pid
)
{
int
add_udp_client
(
struct
sockaddr_in
client_addr
,
pid_t
pid
)
{
int
i
;
for
(
i
=
0
;
i
<
MAX_UDP_CLIENTS
;
i
++
)
{
if
(
clients
[
i
].
pid
==
0
)
{
for
(
i
=
0
;
i
<
MAX_UDP_CLIENTS
;
i
++
)
{
if
(
clients
[
i
].
pid
==
0
)
{
clients
[
i
].
addr
=
client_addr
;
clients
[
i
].
pid
=
pid
;
return
0
;
...
...
@@ -316,10 +355,13 @@ int add_udp_client(struct sockaddr_in client_addr, pid_t pid) {
return
-
1
;
/* No space for new clients */
}
void
remove_udp_client
(
pid_t
pid
)
{
void
remove_udp_client
(
pid_t
pid
)
{
int
i
;
for
(
i
=
0
;
i
<
MAX_UDP_CLIENTS
;
i
++
)
{
if
(
clients
[
i
].
pid
==
pid
)
{
for
(
i
=
0
;
i
<
MAX_UDP_CLIENTS
;
i
++
)
{
if
(
clients
[
i
].
pid
==
pid
)
{
if
(
options
.
log
)
printf
(
"removing client %s, pid: %d
\n
"
,
inet_ntoa
(
clients
[
i
].
addr
.
sin_addr
),
pid
);
clients
[
i
].
pid
=
0
;
...
...
@@ -329,15 +371,18 @@ void remove_udp_client(pid_t pid) {
}
}
int
compare_clients
(
struct
sockaddr_in
client1
,
struct
sockaddr_in
client2
)
{
int
compare_clients
(
struct
sockaddr_in
client1
,
struct
sockaddr_in
client2
)
{
return
(
client1
.
sin_addr
.
s_addr
==
client2
.
sin_addr
.
s_addr
&&
client1
.
sin_port
==
client2
.
sin_port
);
}
int
find_udp_client
(
struct
sockaddr_in
client_addr
)
{
int
find_udp_client
(
struct
sockaddr_in
client_addr
)
{
int
i
;
for
(
i
=
0
;
i
<
MAX_UDP_CLIENTS
;
i
++
)
if
(
clients
[
i
].
pid
>
0
&&
compare_clients
(
clients
[
i
].
addr
,
client_addr
))
{
for
(
i
=
0
;
i
<
MAX_UDP_CLIENTS
;
i
++
)
if
(
clients
[
i
].
pid
>
0
&&
compare_clients
(
clients
[
i
].
addr
,
client_addr
))
{
return
i
;
}
return
-
1
;
...
...
@@ -359,25 +404,32 @@ int use()
int
max_fd
=
(
rc
.
client_socket
>
rc
.
remote_socket
)
?
rc
.
client_socket
:
rc
.
remote_socket
;
/* Waiting for data */
if
(
select
(
max_fd
+
1
,
&
io
,
NULL
,
NULL
,
NULL
)
<
0
)
{
if
(
select
(
max_fd
+
1
,
&
io
,
NULL
,
NULL
,
NULL
)
<
0
)
{
perror
(
"use: select()"
);
break
;
}
if
(
FD_ISSET
(
rc
.
client_socket
,
&
io
))
{
if
(
options
.
proto
==
SOCK_DGRAM
&&
options
.
mode
==
MODE_SERVER
)
{
if
(
options
.
proto
==
SOCK_DGRAM
&&
options
.
mode
==
MODE_SERVER
)
{
count_recv
=
recvfrom
(
rc
.
client_socket
,
buffer
,
sizeof
(
buffer
),
MSG_PEEK
,
(
struct
sockaddr
*
)
&
client_addr
,
&
addr_len
);
if
(
count_recv
<
0
)
{
if
(
count_recv
<
0
)
{
perror
(
"use() - PEEK"
);
return
1
;
}
if
(
rc
.
my_addr
.
sin_port
==
0
)
{
if
(
rc
.
my_addr
.
sin_port
==
0
)
{
rc
.
my_addr
.
sin_addr
.
s_addr
=
client_addr
.
sin_addr
.
s_addr
;
rc
.
my_addr
.
sin_port
=
client_addr
.
sin_port
;
if
(
options
.
log
>
2
)
printf
(
"my address %s:%d
\t
pid: %d
\n
"
,
inet_ntoa
(
client_addr
.
sin_addr
),
ntohs
(
client_addr
.
sin_port
),
getpid
());
}
else
{
if
(
!
compare_clients
(
rc
.
my_addr
,
client_addr
))
{
}
else
{
if
(
!
compare_clients
(
rc
.
my_addr
,
client_addr
))
{
if
(
options
.
log
>
2
)
printf
(
"ignore %s:%d
\t
pid: %d
\n
"
,
inet_ntoa
(
client_addr
.
sin_addr
),
ntohs
(
client_addr
.
sin_port
),
getpid
());
continue
;
...
...
@@ -386,17 +438,17 @@ int use()
}
/* Processing request from local, sending it to remote*/
count_recv
=
(
options
.
proto
==
SOCK_DGRAM
)
?
recvfrom
(
rc
.
client_socket
,
buffer
,
sizeof
(
buffer
),
0
,
(
struct
sockaddr
*
)
&
client_addr
,
&
addr_len
)
:
recv
(
rc
.
client_socket
,
buffer
,
sizeof
(
buffer
),
0
);
count_recv
=
(
options
.
proto
==
SOCK_DGRAM
)
?
recvfrom
(
rc
.
client_socket
,
buffer
,
sizeof
(
buffer
),
0
,
(
struct
sockaddr
*
)
&
client_addr
,
&
addr_len
)
:
recv
(
rc
.
client_socket
,
buffer
,
sizeof
(
buffer
),
0
);
if
(
count_recv
<
0
)
{
if
(
count_recv
<
0
)
{
perror
(
"use: recv(rc.client_socket)"
);
close
(
rc
.
client_socket
);
close
(
rc
.
remote_socket
);
return
1
;
}
if
(
count_recv
==
0
)
{
if
(
count_recv
==
0
)
{
close
(
rc
.
client_socket
);
close
(
rc
.
remote_socket
);
return
0
;
...
...
@@ -417,17 +469,17 @@ int use()
if
(
FD_ISSET
(
rc
.
remote_socket
,
&
io
))
{
/* Processing response from remote, sending it back to local */
count_recv
=
(
options
.
proto
==
SOCK_DGRAM
)
?
recvfrom
(
rc
.
remote_socket
,
buffer
,
sizeof
(
buffer
),
0
,
NULL
,
NULL
)
:
recv
(
rc
.
remote_socket
,
buffer
,
sizeof
(
buffer
),
0
);
count_recv
=
(
options
.
proto
==
SOCK_DGRAM
)
?
recvfrom
(
rc
.
remote_socket
,
buffer
,
sizeof
(
buffer
),
0
,
NULL
,
NULL
)
:
recv
(
rc
.
remote_socket
,
buffer
,
sizeof
(
buffer
),
0
);
if
(
count_recv
<
0
)
{
if
(
count_recv
<
0
)
{
perror
(
"use: recv(rc.remote_socket)"
);
close
(
rc
.
client_socket
);
close
(
rc
.
remote_socket
);
return
1
;
}
if
(
count_recv
==
0
)
{
if
(
count_recv
==
0
)
{
close
(
rc
.
client_socket
);
close
(
rc
.
remote_socket
);
return
0
;
...
...
@@ -436,7 +488,7 @@ int use()
encode
(
buffer
,
count_recv
)
:
decode
(
buffer
,
count_recv
);
/* count_sent = */
(
options
.
proto
==
SOCK_DGRAM
)
?
(
options
.
proto
==
SOCK_DGRAM
)
?
sendto
(
rc
.
client_socket
,
buffer
,
count_recv
,
0
,
(
struct
sockaddr
*
)
&
client_addr
,
addr_len
)
:
send
(
rc
.
client_socket
,
buffer
,
count_recv
,
0
);
...
...
@@ -448,41 +500,50 @@ int use()
return
0
;
}
void
run
()
{
void
run
()
{
if
(
build
()
==
0
)
use
();
}
void
fork_udp
()
{
void
fork_udp
()
{
#ifndef __MINGW32__
pid_t
child_pid
;
int
client_index
=
find_udp_client
(
rc
.
client_addr
);
if
(
client_index
==
-
1
)
{
if
((
child_pid
=
fork
())
==
0
)
{
if
(
client_index
==
-
1
)
{
if
((
child_pid
=
fork
())
==
0
)
{
if
(
options
.
log
)
printf
(
"request from %s, forking %d ...
\n
"
,
inet_ntoa
(
rc
.
client_addr
.
sin_addr
),
getpid
());
run
();
exit
(
0
);
}
if
(
add_udp_client
(
rc
.
client_addr
,
child_pid
)
<
0
)
{
if
(
add_udp_client
(
rc
.
client_addr
,
child_pid
)
<
0
)
{
printf
(
"maximum clients %d reached:
\n
"
,
MAX_UDP_CLIENTS
);
}
/* Reap any zombie processes (clients that exited) */
while
((
child_pid
=
waitpid
(
-
1
,
NULL
,
WNOHANG
))
>
0
)
{
while
((
child_pid
=
waitpid
(
-
1
,
NULL
,
WNOHANG
))
>
0
)
{
remove_udp_client
(
child_pid
);
}
}
else
{
}
else
{
if
(
options
.
log
>
2
)
printf
(
"existing udp client %s, handled by %d ...
\n
"
,
inet_ntoa
(
rc
.
client_addr
.
sin_addr
),
clients
[
client_index
].
pid
);
}
#endif
}
void
fork_tcp
()
{
void
fork_tcp
()
{
#ifndef __MINGW32__
if
(
fork
()
==
0
)
{
if
(
fork
()
==
0
)
{
if
(
options
.
log
)
printf
(
"forking %d ...
\n
"
,
getpid
());
close
(
rc
.
server_socket
);
...
...
@@ -493,30 +554,34 @@ void fork_tcp() {
#endif
}
void
serve
()
{
void
serve
()
{
#ifdef __MINGW32__
run
();
#else
if
(
options
.
fork
)
{
(
options
.
proto
==
SOCK_DGRAM
)
?
fork_udp
()
:
fork_tcp
();
if
(
options
.
fork
)
{
(
options
.
proto
==
SOCK_DGRAM
)
?
fork_udp
()
:
fork_tcp
();
}
else
{
else
{
run
();
}
#endif
}
void
print_usage
(
void
)
{
void
print_usage
(
void
)
{
printf
(
"Usage: %s [config_path] [options]
\n
"
,
name
);
}
void
print_helpinfo
(
void
)
{
void
print_helpinfo
(
void
)
{
printf
(
"Try `%s --help' for more options
\n
"
,
name
);
}
void
print_help
(
void
)
{
void
print_help
(
void
)
{
fprintf
(
stderr
,
"\
Options:
\n
\
...
...
@@ -529,9 +594,9 @@ Options:\n\
--client-address=IP only accept connections from this address
\n
\
--buffer-size=BYTES buffer size
\n
"
#ifndef __MINGW32__
" --fork fork-based concurrency (tcp-only)
\n
"
" --fork fork-based concurrency (tcp-only)
\n
"
#endif
" --log=LEVEL 0-3
\n
\
" --log=LEVEL 0-3
\n
\
--stay-alive don't exit on network errors
\n
\
--mode=MODE client [default] or server
\n
\
--encrypt=ALG 0 - no encryption, 1 - time-based obfuscation
\n
\
...
...
@@ -540,7 +605,8 @@ Options:\n\
\n
"
);
}
void
print_version
(
void
)
{
void
print_version
(
void
)
{
fprintf
(
stderr
,
"
\n
\
bytevia v"
VERSION
"
\n\n
\
...
...
@@ -553,7 +619,8 @@ Written by by Michael Pastushkov <michael@pastushkov.com>\n\n\
"
);
}
void
init_options
()
{
void
init_options
()
{
memset
(
&
options
,
0
,
sizeof
(
options
));
...
...
@@ -570,12 +637,14 @@ void init_options() {
options
.
secret
=
52341
;
}
void
set_options
(
int
argc
,
char
*
argv
[])
{
void
set_options
(
int
argc
,
char
*
argv
[])
{
int
opt
;
int
index
;
do
{
do
{
opt
=
getopt_long
(
argc
,
argv
,
""
,
long_options
,
&
index
);
switch
(
opt
)
{
...
...
@@ -631,66 +700,75 @@ void set_options(int argc, char *argv[]) {
exit
(
0
);
}
}
while
(
opt
!=
-
1
);
}
void
check_options
()
{
void
check_options
()
{
int
opt_error
=
0
;
/* Required options */
if
(
!
options
.
local_port
)
{
if
(
!
options
.
local_port
)
{
printf
(
"%s: %s
\n
"
,
name
,
"missing '--local-port=' option."
);
opt_error
++
;
}
if
(
!
options
.
remote_port
)
{
if
(
!
options
.
remote_port
)
{
printf
(
"%s: %s
\n
"
,
name
,
"missing '--remote-port=' option."
);
opt_error
++
;
}
if
(
!
options
.
remote_host
)
{
if
(
!
options
.
remote_host
)
{
printf
(
"%s: %s
\n
"
,
name
,
"missing '--remote_address=' option."
);
opt_error
++
;
}
if
(
opt_error
)
{
if
(
opt_error
)
{
print_usage
();
print_help
();
exit
(
-
1
);
}
/* Consistency checks */
if
(
options
.
mode
==
MODE_SERVER
&&
!
options
.
stay_alive
)
{
if
(
options
.
mode
==
MODE_SERVER
&&
!
options
.
stay_alive
)
{
printf
(
"%s: option --stay-alive is switched on with --mode=server
\n
"
,
name
);
options
.
stay_alive
=
0
;
}
#ifdef __MINGW32__
if
(
options
.
fork
)
{
if
(
options
.
fork
)
{
printf
(
"%s: option --fork is switched off, Microsoft Windows is incompatible with forking
\n
"
,
name
);
options
.
fork
=
0
;
}
#endif
}
#define MAX_ARGC 20
#define MAX_LINE_LENGTH 256
void
read_config
(
char
*
path
)
{
void
read_config
(
char
*
path
)
{
int
argc
=
0
;
char
*
argv
[
MAX_ARGC
];
char
line
[
MAX_LINE_LENGTH
];
FILE
*
file
=
fopen
(
path
,
"r"
);
if
(
!
file
)
{
if
(
!
file
)
{
perror
(
"cannot read config file"
);
return
;
}
while
(
fgets
(
line
,
sizeof
(
line
),
file
))
{
if
(
strncmp
(
line
,
NAME
,
sizeof
(
NAME
)
-
1
)
==
0
)
{
while
(
fgets
(
line
,
sizeof
(
line
),
file
))
{
if
(
strncmp
(
line
,
NAME
,
sizeof
(
NAME
)
-
1
)
==
0
)
{
char
*
token
=
strtok
(
line
,
"
\t\n
"
);
while
(
token
&&
argc
<
MAX_ARGC
)
{
while
(
token
&&
argc
<
MAX_ARGC
)
{
argv
[
argc
++
]
=
strdup
(
token
);
token
=
strtok
(
NULL
,
"
\t\n
"
);
}
...
...
@@ -700,12 +778,13 @@ void read_config(char *path) {
set_options
(
argc
,
argv
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
int
i
,
ret
;
#ifdef __MINGW32__
WSADATA
info
;
if
(
WSAStartup
(
MAKEWORD
(
1
,
1
),
&
info
)
!=
0
)
if
(
WSAStartup
(
MAKEWORD
(
1
,
1
),
&
info
)
!=
0
)
{
perror
(
"main: WSAStartup()"
);
exit
(
1
);
...
...
@@ -715,8 +794,10 @@ int main(int argc, char *argv[]) {
init_options
();
set_options
(
argc
,
argv
);
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
strncmp
(
argv
[
i
],
"--"
,
2
)
!=
0
)
{
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
strncmp
(
argv
[
i
],
"--"
,
2
)
!=
0
)
{
read_config
(
argv
[
i
]);
break
;
}
...
...
@@ -727,7 +808,8 @@ int main(int argc, char *argv[]) {
signal
(
SIGCHLD
,
SIG_IGN
);
#endif
if
(
options
.
log
)
{
if
(
options
.
log
)
{
printf
(
"%s %s started %s
\n
"
,
NAME
,
VERSION
,
get_current_timestamp
());
printf
(
" protocol: %s
\n
"
,
options
.
proto
==
SOCK_DGRAM
?
"udp"
:
"tcp"
);
printf
(
" local: %s:%d
\n
"
,
options
.
bind_address
,
options
.
local_port
);
...
...
@@ -737,9 +819,7 @@ int main(int argc, char *argv[]) {
printf
(
" fork: %s
\n
"
,
options
.
fork
?
"yes"
:
"no"
);
}
ret
=
(
options
.
proto
==
SOCK_STREAM
)
?
build_tcp
()
:
build_udp
();
ret
=
(
options
.
proto
==
SOCK_STREAM
)
?
build_tcp
()
:
build_udp
();
if
(
ret
!=
0
)
exit
(
1
);
...
...
@@ -750,12 +830,10 @@ int main(int argc, char *argv[]) {
{
serve
();
}
}
while
(
options
.
stay_alive
);
}
while
(
options
.
stay_alive
);
if
(
rc
.
server_socket
)
close
(
rc
.
server_socket
);
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment