Commit d30d6aa5 by Michael Pastushkov

udp update

parent a4c7a7e0
...@@ -65,6 +65,7 @@ static struct option long_options[] = { ...@@ -65,6 +65,7 @@ static struct option long_options[] = {
const char *name = NAME; const char *name = NAME;
unsigned char cipher[256]; unsigned char cipher[256];
int cipher_time; 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]; static char date_str[20];
...@@ -271,7 +272,7 @@ int wait_connection(void) { ...@@ -271,7 +272,7 @@ int wait_connection(void) {
return 1; return 1;
} }
if (options.log) if (options.log && options.proto == SOCK_STREAM)
printf("%s request from %s\n", get_current_timestamp(), inet_ntoa(rc.client_addr.sin_addr)); printf("%s request from %s\n", get_current_timestamp(), inet_ntoa(rc.client_addr.sin_addr));
return 0; return 0;
...@@ -305,6 +306,59 @@ int build(void) { ...@@ -305,6 +306,59 @@ int build(void) {
return 0; return 0;
} }
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) {
clients[i].addr = client_addr;
clients[i].pid = pid;
printf("client %s added ...\n", inet_ntoa(client_addr.sin_addr));
return 0; // Successfully added client
}
}
return -1; // No space for new clients
}
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 i;
for (i=0; i<MAX_UDP_CLIENTS; i++)
if (clients[i].pid > 0 && compare_clients(clients[i].addr, client_addr)) {
printf("client %s found %d ...\n", inet_ntoa(client_addr.sin_addr), i);
return i;
}
return -1;
}
int is_child = 0;
int udp_fork(struct sockaddr_in client_addr) {
pid_t child_pid;
int client_index = find_udp_client(client_addr);
if (client_index == -1) {
if ((child_pid = fork()) == 0) {
printf("new udp request from %s, forking %d ...\n", inet_ntoa(client_addr.sin_addr), getpid());
is_child = 1;
return 0;
}
add_udp_client(client_addr, child_pid);
while (waitpid(-1, NULL, WNOHANG) > 0)
; /* Reap any zombie processes (clients that exited) */
} else {
printf("existing udp client %s, hanled by %d ...\n", inet_ntoa(client_addr.sin_addr), clients[client_index].pid);
}
return 1;
}
int use(void) int use(void)
{ {
fd_set io; fd_set io;
...@@ -347,6 +401,11 @@ int use(void) ...@@ -347,6 +401,11 @@ int use(void)
return 0; return 0;
} }
if (options.fork && options.proto == SOCK_DGRAM && !is_child) {
if (udp_fork(client_addr) == 1)
continue;
}
(options.mode == MODE_SERVER) ? (options.mode == MODE_SERVER) ?
decode(buffer, count_recv) : decode(buffer, count_recv) :
encode(buffer, count_recv); encode(buffer, count_recv);
...@@ -402,15 +461,15 @@ void serve(void) { ...@@ -402,15 +461,15 @@ void serve(void) {
#ifdef __MINGW32__ #ifdef __MINGW32__
run(); run();
#else #else
if (options.fork) { if (options.fork && options.proto == SOCK_STREAM) {
if (fork() == 0) { if (fork() == 0) {
if (options.log) if (options.log)
printf("forking ...\n"); printf("forking TCP %d ...\n", getpid());
close(rc.server_socket); close(rc.server_socket);
run(); run();
exit(0); exit(0);
} }
//close(rc.client_socket); close(rc.client_socket);
} }
else { else {
run(); run();
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#define MODE_CLIENT 0 #define MODE_CLIENT 0
#define MODE_SERVER 1 #define MODE_SERVER 1
#define MAX_UDP_CLIENTS 100
#define LOCAL_PORT_OPTION 'a' #define LOCAL_PORT_OPTION 'a'
#define REMOTE_HOST_OPTION 'b' #define REMOTE_HOST_OPTION 'b'
#define REMOTE_PORT_OPTION 'c' #define REMOTE_PORT_OPTION 'c'
...@@ -55,5 +57,10 @@ struct struct_rc { ...@@ -55,5 +57,10 @@ struct struct_rc {
struct hostent *remote_host; struct hostent *remote_host;
}; };
struct client_info {
struct sockaddr_in addr;
pid_t pid;
};
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment