Commit 0c771f35 by michaelpastushkov

notification tests

parent 7dfbe0ad
......@@ -342,7 +342,8 @@ int build()
memset(&rc.remote_addr, 0, sizeof(rc.remote_addr));
rc.remote_addr.sin_family = AF_INET;
rc.remote_addr.sin_port = htons(options.remote_port);
memcpy(&rc.remote_addr.sin_addr.s_addr, rc.remote_host->h_addr, rc.remote_host->h_length);
// memcpy(&rc.remote_addr.sin_addr.s_addr, rc.remote_host->h_addr, rc.remote_host->h_length);
memcpy(&rc.remote_addr.sin_addr.s_addr, rc.remote_host->h_addr_list[0], rc.remote_host->h_length);
rc.remote_socket = socket(AF_INET, options.proto, 0);
if (rc.remote_socket < 0)
......@@ -403,8 +404,8 @@ void remove_client(pid_t pid)
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);
return (client1.sin_addr.s_addr == client2.sin_addr.s_addr /* &&
client1.sin_port == client2.sin_port */);
}
int find_client(struct sockaddr_in client_addr)
......@@ -418,6 +419,95 @@ int find_client(struct sockaddr_in client_addr)
return -1;
}
int wait_reconnect()
{
struct msghdr message_header;
struct cmsghdr *control_message;
struct iovec io_vector;
char dummy_buffer[100];
char control_buffer[CMSG_SPACE(sizeof(int))];
ssize_t received_length;
int *received_fd_list;
printf("%d waiting for reconnect...\n", getpid());
// Setting up the I/O vector for message reception
io_vector.iov_base = dummy_buffer;
io_vector.iov_len = sizeof(dummy_buffer);
// Initializing the message header
memset(&message_header, 0, sizeof(message_header));
message_header.msg_iov = &io_vector;
message_header.msg_iovlen = 1;
message_header.msg_controllen = CMSG_SPACE(sizeof(int));
message_header.msg_control = control_buffer;
// Receiving the message
received_length = recvmsg(rc.notify_sockets[1], &message_header, 0);
if (received_length < 0)
{
return -1;
}
rc.client_socket = -1; // Default to none received
for (control_message = CMSG_FIRSTHDR(&message_header);
control_message;
control_message = CMSG_NXTHDR(&message_header, control_message))
{
if (control_message->cmsg_level == SOL_SOCKET && control_message->cmsg_type == SCM_RIGHTS)
{
received_fd_list = (int *)CMSG_DATA(control_message);
rc.client_socket = *received_fd_list;
break;
}
}
printf("%d reconnected with socket %d...\n", getpid(), rc.client_socket);
return 0;
}
int notify_reconnect(int client_index)
{
struct msghdr message_header;
struct cmsghdr *control_message;
struct iovec io_vector;
char control_buffer[CMSG_SPACE(sizeof(int))];
char dummy_data[2];
printf("%d notifying for reconnect...\n", getpid());
// Setting up the message header for sending
memset(&message_header, 0, sizeof(message_header));
message_header.msg_controllen = CMSG_SPACE(sizeof(int));
message_header.msg_control = control_buffer;
memset(message_header.msg_control, 0, message_header.msg_controllen);
// Set up the control message
control_message = CMSG_FIRSTHDR(&message_header);
control_message->cmsg_level = SOL_SOCKET;
control_message->cmsg_type = SCM_RIGHTS;
control_message->cmsg_len = CMSG_LEN(sizeof(int));
// Assign client socket
*((int *)CMSG_DATA(control_message)) = rc.client_socket;
// Set up the I/O vector for message transmission
io_vector.iov_base = dummy_data;
io_vector.iov_len = 1;
dummy_data[0] = 0; // Dummy data doesn't matter
message_header.msg_iov = &io_vector;
message_header.msg_iovlen = 1;
// Sending the message
sendmsg(rc.notify_sockets[0], &message_header, 0);
printf("%d notification sent...\n", getpid());
return 0;
}
int use()
{
fd_set io;
......@@ -436,6 +526,7 @@ int use()
/* Waiting for data */
if (select(max_fd + 1, &io, NULL, NULL, NULL) < 0)
{
printf("remote: %d, client: %d\n", rc.remote_socket, rc.client_socket);
perror("use: select()");
break;
}
......@@ -446,7 +537,7 @@ int use()
count_recv = recvfrom(rc.client_socket, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr *)&client_addr, &addr_len);
if (count_recv < 0)
{
perror("use() - PEEK");
perror("use(), peek");
return 1;
}
if (rc.my_addr.sin_port == 0)
......@@ -476,11 +567,16 @@ int use()
{
perror("use: recv(rc.client_socket)");
close(rc.client_socket);
//close(rc.remote_socket);
return 2;
if (wait_reconnect() == 0)
continue;
close(rc.remote_socket);
return 1;
}
if (count_recv == 0)
{
if (options.log > 1)
printf("end of client stream from %s, pid: %d\n", inet_ntoa(rc.client_addr.sin_addr), getpid());
close(rc.client_socket);
close(rc.remote_socket);
return 0;
......@@ -513,6 +609,9 @@ int use()
}
if (count_recv == 0)
{
if (options.log > 1)
printf("end of remote stream to %s, pid: %d\n", inet_ntoa(rc.remote_addr.sin_addr), getpid());
close(rc.client_socket);
close(rc.remote_socket);
return 0;
......@@ -534,91 +633,12 @@ int use()
return 0;
}
#define SOCKET_PATH "/tmp/udp_socket_example" // XXX
int build_notify()
{
if ((rc.notify_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
{
perror("build_socket(), socket");
return -1;
}
memset(&rc.notify_addr, 0, sizeof(rc.notify_addr));
rc.notify_addr.sun_family = AF_UNIX;
strncpy(rc.notify_addr.sun_path, SOCKET_PATH, sizeof(rc.notify_addr.sun_path) - 1);
return 0;
}
int receive_notification()
{
if (build_notify() < 0)
{
return -1;
}
unlink(SOCKET_PATH);
if (bind(rc.notify_socket, (struct sockaddr *)&rc.notify_addr, sizeof(rc.notify_addr)) == -1)
{
perror("receive_notification(), bind");
return -1;
}
printf("waiting for notification ...\n");
ssize_t numBytes = recvfrom(rc.notify_socket, &rc.client_socket, sizeof(rc.client_socket), 0, NULL, NULL);
if (numBytes == -1)
{
perror("receive_notification(), recvfrom");
return -1;
}
printf("notification received: %d\n", rc.client_socket);
close(rc.notify_socket);
unlink(SOCKET_PATH);
return 0;
}
int notify_client(client_index) {
if (build_notify() < 0)
{
return -1;
}
printf("Sending notification: %d\n", rc.client_socket);
if (sendto(rc.notify_socket, &rc.client_socket, sizeof(rc.client_socket), 0, (struct sockaddr *)&rc.notify_addr, sizeof(rc.notify_addr)) == -1)
{
perror("notify_client(), sendto");
return -1;
}
close(rc.notify_socket);
return 0;
}
void run()
{
if (build() == 0)
{
if (options.proto == SOCK_DGRAM)
{
use();
}
else
{
use();
// while (use() == 2)
// {
// if (receive_notification() < 0)
// {
// break;
// }
// }
}
}
}
void show_clients() {
......@@ -635,44 +655,54 @@ void show_clients() {
}
void cleanup_clients() {
printf("cleaning up ...\n");
int i, pid, status;
for (i=0; i<MAX_CLIENTS; i++) {
if (clients[i].pid)
{
pid = waitpid(clients[i].pid, &status, WNOHANG);
printf("checking on %d: %d\n", clients[i].pid, pid);
if (pid)
{
if (options.log)
{
printf("%d exited with code %d\n", clients[i].pid, WEXITSTATUS(status));
}
remove_client(clients[i].pid);
}
}
}
if (options.log > 1){
show_clients();
}
}
void forking()
{
#ifndef __MINGW32__
pid_t child_pid;
cleanup_clients();
int client_index = find_client(rc.client_addr);
if (client_index == -1)
{
if (options.proto == SOCK_STREAM)
{
if (socketpair(AF_UNIX, SOCK_STREAM, 0, rc.notify_sockets) == -1)
{
perror("socketpair");
return;
}
}
if ((child_pid = fork()) == 0)
{
/* Child process */
if (options.log)
printf("forking %d ...\n", getpid());
if (options.proto == SOCK_STREAM)
{
close(rc.server_socket);
close(rc.notify_sockets[0]);
}
run();
if (options.log)
printf("ending %d ...\n", getpid());
exit(0);
}
......@@ -680,43 +710,23 @@ void forking()
/* Main process */
if (options.proto == SOCK_STREAM) {
close(rc.client_socket);
close(rc.notify_sockets[1]);
}
if (add_client(rc.client_addr, child_pid) < 0)
{
printf("maximum clients %d reached: \n", MAX_CLIENTS);
}
cleanup_clients();
if (options.log > 1)
show_clients();
}
else
{
/* Previously known client */
notify_client(client_index);
if (options.log > 2)
printf("client %s handled by %d ...\n", inet_ntoa(rc.client_addr.sin_addr), clients[client_index].pid);
}
#endif
}
/*
void fork_tcp()
{
#ifndef __MINGW32__
if (fork() == 0)
{
if (options.log)
printf("forking %d ...\n", getpid());
close(rc.server_socket);
run();
exit(0);
notify_reconnect(client_index);
printf("connection %d from %s handled by %d ...\n",
rc.client_socket, inet_ntoa(rc.client_addr.sin_addr), clients[client_index].pid);
}
close(rc.client_socket);
#endif
}
*/
void serve()
{
......@@ -972,8 +982,6 @@ int main(int argc, char *argv[])
signal(SIGCHLD, SIG_IGN);
#endif
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);
......@@ -981,7 +989,6 @@ int main(int argc, char *argv[])
printf(" mode: %s\n", options.mode == MODE_SERVER ? "server" : "client");
printf(" encrypt: %s\n", options.encrypt ? "yes" : "no");
printf(" fork: %s\n", options.fork ? "yes" : "no");
}
ret = (options.proto == SOCK_STREAM) ? build_tcp() : build_udp();
......
......@@ -58,8 +58,7 @@ struct struct_rc {
struct sockaddr_in my_addr;
struct hostent *remote_host;
int notify_socket;
struct sockaddr_un notify_addr;
int notify_sockets[2];
};
struct client_info {
......
#!/bin/sh
gcc -o bytevia bytevia.c && ./bytevia --local-port=1948 --remote-host=localhost --remote-port=1949 --secret=52341 --encrypt=1 --log=2
gcc -o bytevia bytevia.c && ./bytevia --local-port=1948 --remote-host=localhost --remote-port=1984 --secret=52341 --encrypt=1 --log=2
#!/bin/sh
gcc -o bytevia bytevia.c && ./bytevia --local-port=1949 --remote-host=p4pn.net --remote-port=1948 --mode=server --secret=52341 --fork --encrypt=1 --log=2
gcc -o bytevia bytevia.c && ./bytevia --local-port=1984 --remote-host=p4pn.net --remote-port=1948 --mode=server --secret=52341 --fork --encrypt=1 --log=2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#define LOCAL_PORT 1984
#define REMOTE_IP "52.204.74.175"
#define REMOTE_PORT 3389
#define BUFFER_SIZE 4096
void error_exit(const char *message) {
perror(message);
exit(EXIT_FAILURE);
}
#include <signal.h>
// Global pipe file descriptors
int pipefd[2];
volatile sig_atomic_t signal_received = 0; // Signal flag for notification
int main() {
int local_socket, remote_socket;
struct sockaddr_in local_addr, remote_addr, client_addr;
socklen_t addr_len = sizeof(struct sockaddr_in);
char buffer[BUFFER_SIZE];
fd_set read_fds;
// Signal handler that sets the flag when a signal is received
void handle_signal(int sig)
{
signal_received = 1;
}
// Create local socket
if ((local_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
error_exit("Local socket creation failed");
int main()
{
// Create a pipe for parent-child communication
if (pipe(pipefd) == -1)
{
perror("pipe");
exit(1);
}
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
local_addr.sin_port = htons(LOCAL_PORT);
pid_t pid = fork();
// Bind the local socket to 127.0.0.1:1984
if (bind(local_socket, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
error_exit("Binding local socket failed");
if (pid == -1)
{
perror("fork");
exit(1);
}
// Create remote socket
if ((remote_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
error_exit("Remote socket creation failed");
if (pid == 0)
{
// Child process
struct sigaction sa;
sa.sa_handler = handle_signal;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
// Set up signal handler for SIGUSR1
if (sigaction(SIGUSR1, &sa, NULL) == -1)
{
perror("sigaction");
exit(1);
}
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr(REMOTE_IP);
remote_addr.sin_port = htons(REMOTE_PORT);
printf("UDP Proxy running on 127.0.0.1:%d, forwarding to %s:%d\n", LOCAL_PORT, REMOTE_IP, REMOTE_PORT);
printf("Child waiting for signal and data...\n");
while (1) {
FD_ZERO(&read_fds);
FD_SET(local_socket, &read_fds);
FD_SET(remote_socket, &read_fds);
int max_fd = (local_socket > remote_socket) ? local_socket : remote_socket;
int activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
if (activity < 0) {
error_exit("select() error");
// Wait for the signal from parent
while (!signal_received)
{
pause(); // Wait for signal
}
// Traffic from local (127.0.0.1:1984) to remote (52.204.74.175:3389)
if (FD_ISSET(local_socket, &read_fds)) {
int received = recvfrom(local_socket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
if (received < 0) {
error_exit("recvfrom() failed");
}
// Once signal is received, read the integer data from the pipe
close(pipefd[1]); // Close unused write end of the pipe
int received_data;
read(pipefd[0], &received_data, sizeof(received_data));
buffer[received] = '\0'; // Null-terminate for safety
printf("Child received data: %d\n", received_data);
close(pipefd[0]);
if (sendto(remote_socket, buffer, received, 0, (struct sockaddr *)&remote_addr, addr_len) < 0) {
error_exit("sendto() to remote failed");
exit(0);
}
else
{
// Parent process
close(pipefd[0]); // Close unused read end of the pipe
printf("Forwarded %d bytes from local to remote\n", received);
}
sleep(1); // Give the child time to set up
// Traffic from remote (52.204.74.175:3389) back to local (127.0.0.1:1984)
if (FD_ISSET(remote_socket, &read_fds)) {
int received = recvfrom(remote_socket, buffer, BUFFER_SIZE, 0, NULL, NULL);
if (received < 0) {
error_exit("recvfrom() from remote failed");
}
// The integer to send to the child
int data_to_send = 42;
buffer[received] = '\0'; // Null-terminate for safety
// Send the signal to the child to notify it
printf("Parent sending signal to child and writing data to pipe.\n");
kill(pid, SIGUSR1);
if (sendto(local_socket, buffer, received, 0, (struct sockaddr *)&client_addr, addr_len) < 0) {
error_exit("sendto() to local failed");
}
// Write the integer data to the pipe
write(pipefd[1], &data_to_send, sizeof(data_to_send));
printf("Forwarded %d bytes from remote to local\n", received);
}
}
close(pipefd[1]); // Close the write end of the pipe
close(local_socket);
close(remote_socket);
// Wait for the child to finish
wait(NULL);
printf("Parent finished.\n");
}
return 0;
}
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