BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 include_guard "port_forwarding"
2  
3 template port_forwarding {
4 alias("_arg0") forwardings_file;
5 alias("_arg1") template_forward;
6  
7 # Map which holds the set of current port forwardings.
8 # Enties are: {protocol, port_start, port_end, dest_addr}:""
9 value([]) map;
10  
11 # Blocker which is initially down and is toggled down-up
12 # whenever the forwarding change.
13 blocker() update_blocker;
14  
15 # Process manager, each forwarding has a port_forwarding__instance process.
16 # The process identifiers are the same as the keys in the map.
17 process_manager() mgr;
18  
19 # Spawn a process for dealing with storage of port forwardings on disk.
20 spawn("port_forwarding__stored", {});
21 }
22  
23 template port_forwarding__instance {
24 alias("_caller") pf;
25 alias("_arg0") protocol;
26 alias("_arg1") port_start;
27 alias("_arg2") port_end;
28 alias("_arg3") dest_addr;
29  
30 log("notice", "adding port forwarding ", protocol, ":", port_start, ":", port_end, " to ", dest_addr);
31 log_r("notice", "removed port forwarding ", protocol, ":", port_start, ":", port_end, " to ", dest_addr);
32  
33 # Do the forwarding.
34 call_with_caller_target(pf.template_forward, {protocol, port_start, port_end, dest_addr}, "pf._caller");
35 }
36  
37 template port_forwarding_add {
38 alias(_arg0) pf;
39 alias("_arg1") protocol;
40 alias("_arg2") port_start;
41 alias("_arg3") port_end;
42 alias("_arg4") dest_addr;
43  
44 var("false") succeeded;
45 var("") error_text;
46 var("true") not_finished;
47 backtrack_point() finished_point;
48  
49 If (not_finished) {
50 # Check for conflicts with existing forwardings.
51 Foreach (pf.map.keys As entry) {
52 value(entry) entry;
53 entry->get("0") e_protocol;
54 entry->get("1") e_port_start;
55 entry->get("2") e_port_end;
56  
57 val_different(protocol, e_protocol) different_protocol;
58 num_lesser(port_end, e_port_start) before;
59 num_greater(port_start, e_port_end) after;
60 or(different_protocol, before, after) no_conflict;
61 not(no_conflict) conflict;
62  
63 If (conflict) {
64 error_text->set("Port forwarding conflicts with an existing forwarding.");
65 not_finished->set("false");
66 finished_point->go();
67 };
68 };
69  
70 # Build entry key.
71 var({protocol, port_start, port_end, dest_addr}) key;
72  
73 # Insert to map and toggle blocker.
74 pf.map->insert(key, "");
75 pf.update_blocker->downup();
76  
77 # Start process.
78 pf.mgr->start(key, "port_forwarding__instance", {protocol, port_start, port_end, dest_addr});
79  
80 succeeded->set("true");
81 not_finished->set("false");
82 finished_point->go();
83 };
84 }
85  
86 template port_forwarding_remove {
87 alias(_arg0) pf;
88 alias("_arg1") protocol;
89 alias("_arg2") port_start;
90 alias("_arg3") port_end;
91 alias("_arg4") dest_addr;
92  
93 var("false") succeeded;
94 var("") error_text;
95 var("true") not_finished;
96 backtrack_point() finished_point;
97  
98 If (not_finished) {
99 # Build entry key.
100 var({protocol, port_start, port_end, dest_addr}) key;
101  
102 # Check if the forwarding exists.
103 pf.map->try_get(key) entry;
104 not(entry.exists) does_not_exist;
105 If (does_not_exist) {
106 error_text->set("Port forwarding does not exist.");
107 not_finished->set("false");
108 finished_point->go();
109 };
110  
111 # Stop process.
112 pf.mgr->stop(key);
113  
114 # Remove from map and toggle blocker.
115 pf.map->remove(key);
116 pf.update_blocker->downup();
117  
118 succeeded->set("true");
119 not_finished->set("false");
120 finished_point->go();
121 };
122 }
123  
124 template port_forwarding__stored {
125 alias("_caller") pf;
126  
127 # Create file if it doesn't exist.
128 file_stat(pf.forwardings_file) stat;
129 If (stat.succeeded) { print(); } Else {
130 file_write(pf.forwardings_file, "{}\n");
131 };
132  
133 # Read port forwardings from file.
134 file_read(pf.forwardings_file) data;
135 from_string(data) forwardings;
136  
137 # Add them.
138 Foreach (forwardings As fwd) {
139 value(fwd) fwd;
140 fwd->get("0") protocol;
141 fwd->get("1") port_start;
142 fwd->get("2") port_end;
143 fwd->get("3") dest_addr;
144 call("port_forwarding_add", {"_caller.pf", protocol, port_start, port_end, dest_addr});
145 };
146  
147 # Write forwardings to file on exit.
148 imperative("<none>", {}, "port_forwarding__write", {}, "6000");
149  
150 # Also write forwardings whenever they are changed.
151 pf.update_blocker->use();
152 call("port_forwarding__write", {});
153 }
154  
155 template port_forwarding__write {
156 alias("_caller.pf") pf;
157  
158 # Convert forwardings to string.
159 to_string(pf.map.keys) data;
160 concat(data, "\n") data;
161  
162 # Build name of temporary file.
163 concat(pf.forwardings_file, ".new") temp_file;
164  
165 # Write temporary file.
166 file_write(temp_file, data);
167  
168 # Move to live file.
169 runonce({"/bin/mv", temp_file, pf.forwardings_file});
170 }