-
Notifications
You must be signed in to change notification settings - Fork 2
/
sr_nat.c
101 lines (70 loc) · 2.74 KB
/
sr_nat.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
#include <signal.h>
#include <assert.h>
#include "sr_nat.h"
#include <unistd.h>
int sr_nat_init(struct sr_nat *nat) { /* Initializes the nat */
assert(nat);
/* Acquire mutex lock */
pthread_mutexattr_init(&(nat->attr));
pthread_mutexattr_settype(&(nat->attr), PTHREAD_MUTEX_RECURSIVE);
int success = pthread_mutex_init(&(nat->lock), &(nat->attr));
/* Initialize timeout thread */
pthread_attr_init(&(nat->thread_attr));
pthread_attr_setdetachstate(&(nat->thread_attr), PTHREAD_CREATE_JOINABLE);
pthread_attr_setscope(&(nat->thread_attr), PTHREAD_SCOPE_SYSTEM);
pthread_attr_setscope(&(nat->thread_attr), PTHREAD_SCOPE_SYSTEM);
pthread_create(&(nat->thread), &(nat->thread_attr), sr_nat_timeout, nat);
/* CAREFUL MODIFYING CODE ABOVE THIS LINE! */
nat->mappings = NULL;
/* Initialize any variables here */
return success;
}
int sr_nat_destroy(struct sr_nat *nat) { /* Destroys the nat (free memory) */
pthread_mutex_lock(&(nat->lock));
/* free nat memory here */
pthread_kill(nat->thread, SIGKILL);
return pthread_mutex_destroy(&(nat->lock)) &&
pthread_mutexattr_destroy(&(nat->attr));
}
void *sr_nat_timeout(void *nat_ptr) { /* Periodic Timout handling */
struct sr_nat *nat = (struct sr_nat *)nat_ptr;
while (1) {
sleep(1.0);
pthread_mutex_lock(&(nat->lock));
time_t curtime = time(NULL);
/* handle periodic tasks here */
pthread_mutex_unlock(&(nat->lock));
}
return NULL;
}
/* Get the mapping associated with given external port.
You must free the returned structure if it is not NULL. */
struct sr_nat_mapping *sr_nat_lookup_external(struct sr_nat *nat,
uint16_t aux_ext, sr_nat_mapping_type type ) {
pthread_mutex_lock(&(nat->lock));
/* handle lookup here, malloc and assign to copy */
struct sr_nat_mapping *copy = NULL;
pthread_mutex_unlock(&(nat->lock));
return copy;
}
/* Get the mapping associated with given internal (ip, port) pair.
You must free the returned structure if it is not NULL. */
struct sr_nat_mapping *sr_nat_lookup_internal(struct sr_nat *nat,
uint32_t ip_int, uint16_t aux_int, sr_nat_mapping_type type ) {
pthread_mutex_lock(&(nat->lock));
/* handle lookup here, malloc and assign to copy. */
struct sr_nat_mapping *copy = NULL;
pthread_mutex_unlock(&(nat->lock));
return copy;
}
/* Insert a new mapping into the nat's mapping table.
Actually returns a copy to the new mapping, for thread safety.
*/
struct sr_nat_mapping *sr_nat_insert_mapping(struct sr_nat *nat,
uint32_t ip_int, uint16_t aux_int, sr_nat_mapping_type type ) {
pthread_mutex_lock(&(nat->lock));
/* handle insert here, create a mapping, and then return a copy of it */
struct sr_nat_mapping *mapping = NULL;
pthread_mutex_unlock(&(nat->lock));
return mapping;
}