-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomm.c
169 lines (139 loc) · 5.63 KB
/
comm.c
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//
// Created by Ben on 7/18/22.
//
#include "comm.h"
#include "graph.h"
#include "layer2/layer2.h"
#include <sys/socket.h>
#include <pthread.h>
#include <netinet/in.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include "net.h"
#include <unistd.h>
extern void layer2_frame_recv(node_t *node, interface_t *interface, char *pkt, unsigned int pkt_size);
static int _send_pkt_out(int sock_fd, char *pkt_data, unsigned int pkt_size, unsigned int dst_udp_port_no){
int rc;
struct sockaddr_in dest_addr;
struct hostent *host = (struct hostent *) gethostbyname("127.0.0.1");
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = dst_udp_port_no;
dest_addr.sin_addr = *((struct in_addr *)host->h_addr);
rc = sendto(sock_fd, pkt_data, pkt_size, 0,
(struct sockaddr *)&dest_addr, sizeof(struct sockaddr));
return rc;
}
static unsigned int udp_port_number = 40000;
static unsigned int get_next_udp_port_number(){
return udp_port_number++;
}
void init_udp_socket(node_t *node){
node->udp_port_number = get_next_udp_port_number();
int udp_sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in node_addr;
node_addr.sin_family = AF_INET;
node_addr.sin_port = node->udp_port_number;
node_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(udp_sock_fd, (struct sockaddr*)&node_addr, sizeof(struct sockaddr)) == -1){
printf("Error: socket bind failed for node %s\n", node->node_name);
return;
}
node->udp_sock_fd = udp_sock_fd;
}
static char recv_buffer[MAX_PACKET_BUFFER_SIZE];
static char send_buffer[MAX_PACKET_BUFFER_SIZE];
int pkt_receive(node_t *node, interface_t *interface, char *pkt, unsigned int pkt_size){
pkt = pkt_buffer_shift_right(pkt, pkt_size, MAX_PACKET_BUFFER_SIZE - IF_NAME_SIZE);
layer2_frame_recv(node, interface, pkt, pkt_size);
//printf("Msg received = %s, on node =%s, Interface = %s\n", pkt, node->node_name, interface->if_name);
return 0;
}
static void _pkt_receive(node_t *receiving_node, char *pkt_with_aux_data, unsigned int pkt_size){
char *recv_intf_name = pkt_with_aux_data;
interface_t *recv_intf = get_node_if_by_name(receiving_node, recv_intf_name);
if(!recv_intf){
printf("Error : Pkt recvd on unknown interface %s on node %s\n",
recv_intf->if_name, receiving_node->node_name);
return;
}
pkt_receive(receiving_node, recv_intf, pkt_with_aux_data + IF_NAME_SIZE,
pkt_size - IF_NAME_SIZE);
}
static void _network_start_pkt_receiver_thread(void* arg){
node_t *node;
glthread_t *curr;
fd_set active_sock_fd_set, backup_sock_fd_set;
int sock_max_fd = 0;
int bytes_recvd = 0;
graph_t *topo = (void*) arg;
int addr_len = sizeof(struct sockaddr);
FD_ZERO(&active_sock_fd_set);
FD_ZERO(&backup_sock_fd_set);
struct sockaddr_in sender_addr;
ITERATE_GLTHREAD_BEGIN(&topo->node_list, curr){
node = graph_glue_to_node(curr);
if (!node->udp_sock_fd)
continue;
if (node->udp_sock_fd > sock_max_fd)
sock_max_fd = node->udp_sock_fd;
FD_SET(node->udp_sock_fd, &backup_sock_fd_set);
}ITERATE_GLTHREAD_END(&topo->node_list, curr);
while(1){
memcpy(&active_sock_fd_set, &backup_sock_fd_set, sizeof(fd_set));
select(sock_max_fd + 1, &active_sock_fd_set, NULL, NULL, NULL);
ITERATE_GLTHREAD_BEGIN(&topo->node_list, curr){
node = graph_glue_to_node(curr);
if(FD_ISSET(node->udp_sock_fd, &active_sock_fd_set)){
memset(recv_buffer, 0, MAX_PACKET_BUFFER_SIZE);
bytes_recvd = recvfrom(node->udp_sock_fd, (char*)recv_buffer, MAX_PACKET_BUFFER_SIZE, 0,
(struct sockaddr*)&sender_addr, &addr_len);
_pkt_receive(node, recv_buffer, bytes_recvd);
}
}ITERATE_GLTHREAD_END(&topo->node_list, curr);
}
}
void network_start_pkt_receiver_thread(graph_t *topo){
pthread_attr_t attr;
pthread_t recv_pkt_thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&recv_pkt_thread, &attr, _network_start_pkt_receiver_thread, (void*)topo);
}
int send_pkt_out(char *pkt, unsigned int pkt_size, interface_t *interface){
int rc = 0;
node_t *sending_node = interface->att_node;
node_t *nbr_node = get_nbr_node(interface);
if(!nbr_node) return -1;
unsigned int dst_udp_port_no = nbr_node->udp_port_number;
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sock < 0){
printf("Error : Sending socket Creation failed , errno = %d", errno);
return -1;
}
interface_t *other_interface = &interface->link->intf1 == interface ? \
&interface->link->intf2 : &interface->link->intf1;
memset(send_buffer, 0, MAX_PACKET_BUFFER_SIZE);
char *pkt_with_aux_data = send_buffer;
strncpy(pkt_with_aux_data, other_interface->if_name, IF_NAME_SIZE);
pkt_with_aux_data[IF_NAME_SIZE - 1] = '\0';
memcpy(pkt_with_aux_data + IF_NAME_SIZE, pkt, pkt_size);
rc = _send_pkt_out(sock, pkt_with_aux_data, pkt_size + IF_NAME_SIZE,
dst_udp_port_no);
close(sock);
return rc;
}
int send_pkt_flood_l2_intf_only(node_t *node, interface_t *exempted_intf, char *pkt, unsigned int pkt_size){
unsigned int i = 0;
interface_t *intf;
for( ; i < MAX_INTF_PER_NODE; i++){
intf = node->intf[i];
if(!intf) return 0;
if(intf == exempted_intf ||
!IF_L2_MODE(intf))
continue;
send_pkt_out(pkt, pkt_size, intf);
}
}