00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include <errno.h>
00067 #include <stdlib.h>
00068 #include <stdio.h>
00069 #include <time.h>
00070 #include <string.h>
00071 #include <sys/time.h>
00072 #include <sys/types.h>
00073 #include <unistd.h>
00074 #include <signal.h>
00075 #include <fcntl.h>
00076 #include <assert.h>
00077
00078 #include "gwlib/gwlib.h"
00079 #include "msg.h"
00080 #include "bearerbox.h"
00081
00082
00083
00084 extern volatile sig_atomic_t bb_status;
00085 extern List *incoming_wdp;
00086
00087 extern Counter *incoming_wdp_counter;
00088 extern Counter *outgoing_wdp_counter;
00089
00090 extern List *flow_threads;
00091 extern List *suspended;
00092 extern List *isolated;
00093
00094
00095
00096 static volatile sig_atomic_t udp_running;
00097 static List *udpc_list;
00098
00099
00100 typedef struct _udpc {
00101 int fd;
00102 Octstr *addr;
00103 List *outgoing_list;
00104 long receiver;
00105 } Udpc;
00106
00107
00108
00109
00110
00111 static Octstr *allow_ip;
00112 static Octstr *deny_ip;
00113
00114
00115
00116
00117 static void udpc_destroy(Udpc *udpc);
00118
00119
00120
00121
00122
00123 static void udp_receiver(void *arg)
00124 {
00125 Octstr *datagram, *cliaddr;
00126 int ret;
00127 Msg *msg;
00128 Udpc *conn = arg;
00129 Octstr *ip;
00130
00131 gwlist_add_producer(incoming_wdp);
00132 gwlist_add_producer(flow_threads);
00133 gwthread_wakeup(MAIN_THREAD_ID);
00134
00135
00136 while (bb_status != BB_DEAD && bb_status != BB_SHUTDOWN) {
00137
00138 gwlist_consume(isolated);
00139
00140 if (read_available(conn->fd, 100000) < 1)
00141 continue;
00142
00143 ret = udp_recvfrom(conn->fd, &datagram, &cliaddr);
00144 if (ret == -1) {
00145 if (errno == EAGAIN)
00146
00147 continue;
00148
00149 error(errno, "Failed to receive an UDP");
00150
00151
00152
00153
00154
00155 continue;
00156 }
00157
00158
00159 ip = udp_get_ip(cliaddr);
00160 if (!is_allowed_ip(allow_ip, deny_ip, ip)) {
00161 warning(0, "UDP: Discarding packet from %s, IP is denied.",
00162 octstr_get_cstr(ip));
00163 octstr_destroy(datagram);
00164 } else {
00165 debug("bb.udp", 0, "datagram received");
00166 msg = msg_create(wdp_datagram);
00167
00168 msg->wdp_datagram.source_address = udp_get_ip(cliaddr);
00169 msg->wdp_datagram.source_port = udp_get_port(cliaddr);
00170 msg->wdp_datagram.destination_address = udp_get_ip(conn->addr);
00171 msg->wdp_datagram.destination_port = udp_get_port(conn->addr);
00172 msg->wdp_datagram.user_data = datagram;
00173
00174 gwlist_produce(incoming_wdp, msg);
00175 counter_increase(incoming_wdp_counter);
00176 }
00177
00178 octstr_destroy(cliaddr);
00179 octstr_destroy(ip);
00180 }
00181 gwlist_remove_producer(incoming_wdp);
00182 gwlist_remove_producer(flow_threads);
00183 }
00184
00185
00186
00187
00188
00189
00190 static int send_udp(int fd, Msg *msg)
00191 {
00192 Octstr *cliaddr;
00193 int ret;
00194
00195 cliaddr = udp_create_address(msg->wdp_datagram.destination_address,
00196 msg->wdp_datagram.destination_port);
00197 ret = udp_sendto(fd, msg->wdp_datagram.user_data, cliaddr);
00198 if (ret == -1)
00199 error(0, "WDP/UDP: could not send UDP datagram");
00200 octstr_destroy(cliaddr);
00201 return ret;
00202 }
00203
00204
00205 static void udp_sender(void *arg)
00206 {
00207 Msg *msg;
00208 Udpc *conn = arg;
00209
00210 gwlist_add_producer(flow_threads);
00211 while(bb_status != BB_DEAD) {
00212
00213 gwlist_consume(suspended);
00214
00215 if ((msg = gwlist_consume(conn->outgoing_list)) == NULL)
00216 break;
00217
00218 debug("bb.udp", 0, "udp: sending message");
00219
00220 if (send_udp(conn->fd, msg) == -1)
00221
00222
00223
00224 {
00225 msg_destroy(msg);
00226 continue;
00227 }
00228 counter_increase(outgoing_wdp_counter);
00229 msg_destroy(msg);
00230 }
00231 gwthread_join(conn->receiver);
00232
00233 udpc_destroy(conn);
00234 gwlist_remove_producer(flow_threads);
00235 }
00236
00237
00238
00239
00240
00241
00242 static Udpc *udpc_create(int port, char *interface_name)
00243 {
00244 Udpc *udpc;
00245 Octstr *os;
00246 int fl;
00247
00248 udpc = gw_malloc(sizeof(Udpc));
00249 udpc->fd = udp_bind(port, interface_name);
00250
00251 os = octstr_create(interface_name);
00252 udpc->addr = udp_create_address(os, port);
00253 octstr_destroy(os);
00254 if (udpc->addr == NULL) {
00255 error(0, "updc_create: could not resolve interface <%s>",
00256 interface_name);
00257 close(udpc->fd);
00258 gw_free(udpc);
00259 return NULL;
00260 }
00261
00262 fl = fcntl(udpc->fd, F_GETFL);
00263 fcntl(udpc->fd, F_SETFL, fl | O_NONBLOCK);
00264
00265 os = udp_get_ip(udpc->addr);
00266 debug("bb.udp", 0, "udpc_create: Bound to UDP <%s:%d>",
00267 octstr_get_cstr(os), udp_get_port(udpc->addr));
00268
00269 octstr_destroy(os);
00270
00271 udpc->outgoing_list = gwlist_create();
00272
00273 return udpc;
00274 }
00275
00276
00277 static void udpc_destroy(Udpc *udpc)
00278 {
00279 if (udpc == NULL)
00280 return;
00281
00282 if (udpc->fd >= 0)
00283 close(udpc->fd);
00284 octstr_destroy(udpc->addr);
00285 gw_assert(gwlist_len(udpc->outgoing_list) == 0);
00286 gwlist_destroy(udpc->outgoing_list, NULL);
00287
00288 gw_free(udpc);
00289 }
00290
00291
00292 static int add_service(int port, char *interface_name)
00293 {
00294 Udpc *udpc;
00295
00296 if ((udpc = udpc_create(port, interface_name)) == NULL)
00297 goto error;
00298 gwlist_add_producer(udpc->outgoing_list);
00299
00300 udpc->receiver = gwthread_create(udp_receiver, udpc);
00301 if (udpc->receiver == -1)
00302 goto error;
00303
00304 if (gwthread_create(udp_sender, udpc) == -1)
00305 goto error;
00306
00307 gwlist_append(udpc_list, udpc);
00308 return 0;
00309
00310 error:
00311 error(0, "Failed to start UDP receiver/sender thread");
00312 udpc_destroy(udpc);
00313 return -1;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 int udp_start(Cfg *cfg)
00324 {
00325 CfgGroup *grp;
00326 Octstr *iface;
00327 List *ifs;
00328 int allow_wtls;
00329
00330 if (udp_running) return -1;
00331
00332 debug("bb.udp", 0, "starting UDP sender/receiver module");
00333
00334 grp = cfg_get_single_group(cfg, octstr_imm("core"));
00335 iface = cfg_get(grp, octstr_imm("wdp-interface-name"));
00336 if (iface == NULL) {
00337 error(0, "Missing wdp-interface-name variable, cannot start UDP");
00338 return -1;
00339 }
00340
00341 allow_ip = cfg_get(grp, octstr_imm("udp-allow-ip"));
00342 deny_ip = cfg_get(grp, octstr_imm("udp-deny-ip"));
00343
00344
00345 grp = cfg_get_single_group(cfg, octstr_imm("wtls"));
00346 allow_wtls = grp != NULL ? 1 : 0;
00347
00348 udpc_list = gwlist_create();
00349
00350 ifs = octstr_split(iface, octstr_imm(";"));
00351 octstr_destroy(iface);
00352 while (gwlist_len(ifs) > 0) {
00353 iface = gwlist_extract_first(ifs);
00354 info(0, "Adding interface %s", octstr_get_cstr(iface));
00355 add_service(9200, octstr_get_cstr(iface));
00356 add_service(9201, octstr_get_cstr(iface));
00357
00358 #ifdef HAVE_WTLS_OPENSSL
00359 if (allow_wtls) {
00360 add_service(9202, octstr_get_cstr(iface));
00361 add_service(9203, octstr_get_cstr(iface));
00362 }
00363 #else
00364 if (allow_wtls)
00365 error(0, "These is a 'wtls' group in configuration, but no WTLS support compiled in!");
00366 #endif
00367
00368
00369
00370
00371 octstr_destroy(iface);
00372 }
00373 gwlist_destroy(ifs, NULL);
00374
00375 gwlist_add_producer(incoming_wdp);
00376 udp_running = 1;
00377 return 0;
00378 }
00379
00380
00381
00382
00383
00384
00385 int udp_addwdp(Msg *msg)
00386 {
00387 int i;
00388 Udpc *udpc, *def_udpc;
00389 Octstr *ip;
00390
00391 def_udpc = NULL;
00392 if (!udp_running) return -1;
00393 assert(msg != NULL);
00394 assert(msg_type(msg) == wdp_datagram);
00395
00396 gwlist_lock(udpc_list);
00397
00398 for (i=0; i < gwlist_len(udpc_list); i++) {
00399 udpc = gwlist_get(udpc_list, i);
00400
00401 if (msg->wdp_datagram.source_port == udp_get_port(udpc->addr)) {
00402 def_udpc = udpc;
00403 ip = udp_get_ip(udpc->addr);
00404 if (octstr_compare(msg->wdp_datagram.source_address, ip) == 0) {
00405 octstr_destroy(ip);
00406 gwlist_produce(udpc->outgoing_list, msg);
00407 gwlist_unlock(udpc_list);
00408 return 0;
00409 }
00410 octstr_destroy(ip);
00411 }
00412 }
00413
00414 if (NULL != def_udpc) {
00415 gwlist_produce(def_udpc->outgoing_list, msg);
00416 gwlist_unlock(udpc_list);
00417 return 0;
00418 }
00419
00420 gwlist_unlock(udpc_list);
00421 return -1;
00422 }
00423
00424 int udp_shutdown(void)
00425 {
00426 if (!udp_running) return -1;
00427
00428 debug("bb.thread", 0, "udp_shutdown: Starting avalanche");
00429 gwlist_remove_producer(incoming_wdp);
00430 return 0;
00431 }
00432
00433
00434 int udp_die(void)
00435 {
00436 Udpc *udpc;
00437
00438 if (!udp_running) return -1;
00439
00440
00441
00442
00443 debug("bb.udp", 0, "udp_die: removing producers from udp-lists");
00444
00445 while((udpc = gwlist_consume(udpc_list)) != NULL) {
00446 gwlist_remove_producer(udpc->outgoing_list);
00447 }
00448 gwlist_destroy(udpc_list, NULL);
00449 udp_running = 0;
00450
00451 octstr_destroy(allow_ip);
00452 octstr_destroy(deny_ip);
00453 allow_ip = NULL;
00454 deny_ip = NULL;
00455
00456 return 0;
00457 }
00458
00459
00460 int udp_outgoing_queue(void)
00461 {
00462 int i, q = 0;
00463 Udpc *udpc;
00464
00465 if (!udp_running || udpc_list == NULL)
00466 return 0;
00467
00468 gwlist_lock(udpc_list);
00469 for (i=0; i < gwlist_len(udpc_list); i++) {
00470 udpc = gwlist_get(udpc_list, i);
00471 q += gwlist_len(udpc->outgoing_list);
00472 }
00473 gwlist_unlock(udpc_list);
00474 return q;
00475 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.