-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.c
More file actions
129 lines (115 loc) · 4.07 KB
/
util.c
File metadata and controls
129 lines (115 loc) · 4.07 KB
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
// EE122 Project 2 - util.c
// Xiaodian (Yinyin) Wang and Arnab Mukherji
//
// util.c contains all of the common functions that are used by the senders, router and receivers.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/time.h>
#include <math.h>
#include "common.h"
//Get the socket address, IPv6 or IPv6 (taken from Beej's guide)
/*If the sa_family field is AF_INET (IPv4), return the IPv4 address. Otherwise return the IPv6 address.*/
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
//Enqueue packets to linked list
int enqueue (struct q_elem *elem, struct router_q *q, unsigned int max_q_size) {
if (q->q_size >= max_q_size) {//If queue size is at max, drop incoming packets
q->drop_cnt++;
return 1;
}
if (q->head == NULL) {
q->head = elem;
} else {
q->tail->next = elem;
}
q->tail = elem;
q->q_size++;
elem->next = NULL;
//printf("%s %d Queue size is %d\n", __func__, __LINE__, q->q_size);
return 0;
}
//Dequeue packets from linked list
struct q_elem *dequeue (struct router_q *q) {
struct q_elem *elem = NULL;
//printf("%s %d Queue size is %d\n", __func__, __LINE__, q->q_size);
if (q->head == NULL) {
return NULL;
} else {
elem = q->head;
q->head = q->head->next;
q->q_size--;
}
if (q->head == NULL) {
q->tail = NULL;
q->q_size = 0;
}
return elem;
}
//Packet delay time, generates a time delay according to a poisson distribution
/*
Because the rand() function isn't really random even when you seed random() with
the current time, it generates exponential numbers at poisson loop times. Not as
precise but has better "randomness" than without the looping (Otherwise you get
consistently very similar exponential values).
*/
void poisson_delay(double mean) {
double l = 0, p = 1;
double delay_time = 0, rand_num = 0;
struct timeval curr_time;
l = exp(-1*mean);
gettimeofday(&curr_time, NULL);
srand(curr_time.tv_usec); //seed random number generator with current time
do {
rand_num = rand()/(double)RAND_MAX;
//printf("%s: The random number is %f\n", __func__, rand_num);
p = p * rand_num;
} while (p > l);
delay_time = -log(1.0 - rand_num)*mean;
//printf("*****%s delay is: %f milliseconds\n",__func__, delay_time);
usleep((useconds_t) (delay_time * 1000)); //usleep is in usec, want millisec
}
//Generates a time delay according to a uniform distribution.
//Given an input b, will delay a random time within the uniform
//distribution of [0, b].
void uniform_delay(int b) {
int delay_time = 0, rand_num = 0;
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
srand(curr_time.tv_usec); //seed randnum generator w/ current time
rand_num = rand()%(b+1);
delay_time = rand_num * 1000; //get delay time in millisec
//printf("%s in util.c: uniform delay time is %d ms\n", __func__, delay_time/1000);
usleep((useconds_t) delay_time);
}
//Function to retreive the port for a given receiver ID
char port_str[32];
char *get_receiver_port(unsigned int receiver_id) {
unsigned int port;
port = (RECEIVER_PORT_BASE + (receiver_id - 1));
sprintf(port_str, "%d", port);
return port_str;
}
/*Function to obtain a running average, given a count of total elements and
the cumulative sum of the elements themselves. Used by the router to
obtain the average length of each queue. Also used by the receiver to
obtain the average packet delay from the sender to the receiver.*/
unsigned int avg;
unsigned int running_avg(unsigned int count, unsigned int cumulative) {
avg = cumulative / count;
//printf("%s in util.c: is currently %d\n",__func__, avg);
return avg;
}