Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

bb_udp.c File Reference

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <assert.h>
#include "gwlib/gwlib.h"
#include "msg.h"
#include "bearerbox.h"

Include dependency graph for bb_udp.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  _udpc

Typedefs

typedef _udpc Udpc

Functions

void udpc_destroy (Udpc *udpc)
void udp_receiver (void *arg)
int send_udp (int fd, Msg *msg)
void udp_sender (void *arg)
Udpcudpc_create (int port, char *interface_name)
int add_service (int port, char *interface_name)
int udp_start (Cfg *cfg)
int udp_addwdp (Msg *msg)
int udp_shutdown (void)
int udp_die (void)
int udp_outgoing_queue (void)

Variables

volatile sig_atomic_t bb_status
Listincoming_wdp
Counterincoming_wdp_counter
Counteroutgoing_wdp_counter
Listflow_threads
Listsuspended
Listisolated
volatile sig_atomic_t udp_running
Listudpc_list
Octstrallow_ip
Octstrdeny_ip


Typedef Documentation

typedef struct _udpc Udpc
 

Referenced by add_service(), udp_addwdp(), udp_addwdp_from_client(), udp_addwdp_from_server(), udp_die(), udp_outgoing_queue(), udp_receiver(), udp_sender(), udpc_create(), udpc_destroy(), and udpc_find_mapping().


Function Documentation

int add_service int  port,
char *  interface_name
[static]
 

Definition at line 292 of file bb_udp.c.

References error(), gwlist_add_producer(), gwlist_append(), gwthread_create, _udpc::outgoing_list, port, _udpc::receiver, udp_receiver(), udp_sender(), Udpc, udpc_create(), udpc_destroy(), and udpc_list.

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 }

Here is the call graph for this function:

int send_udp int  fd,
Msg msg
[static]
 

Definition at line 190 of file bb_udp.c.

References error(), octstr_destroy(), udp_create_address(), and udp_sendto().

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 }

Here is the call graph for this function:

int udp_addwdp Msg msg  ) 
 

Definition at line 385 of file bb_udp.c.

References _udpc::addr, gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_produce(), gwlist_unlock(), msg_type, octstr_compare(), octstr_destroy(), _udpc::outgoing_list, udp_get_ip(), udp_get_port(), Udpc, udpc_list, and wdp_datagram.

Referenced by wdp_router().

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     /* select in which list to add this */
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 }

Here is the call graph for this function:

int udp_die void   ) 
 

Definition at line 434 of file bb_udp.c.

References allow_ip, debug(), deny_ip, gwlist_consume(), gwlist_destroy(), gwlist_remove_producer(), octstr_destroy(), _udpc::outgoing_list, udp_running, Udpc, and udpc_list.

Referenced by service_router(), and wdp_router().

00435 {
00436     Udpc *udpc;
00437 
00438     if (!udp_running) return -1;
00439     
00440     /*
00441      * remove producers from all outgoing lists.
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 }

Here is the call graph for this function:

int udp_outgoing_queue void   ) 
 

Definition at line 460 of file bb_udp.c.

References gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_unlock(), _udpc::outgoing_list, udp_running, Udpc, and udpc_list.

Referenced by bb_print_status().

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 }

Here is the call graph for this function:

void udp_receiver void *  arg  )  [static]
 

Definition at line 123 of file bb_udp.c.

References _udpc::addr, allow_ip, BB_DEAD, bb_status, counter_increase(), debug(), deny_ip, error(), _udpc::fd, flow_threads, gwlist_add_producer(), gwlist_consume(), gwlist_produce(), gwlist_remove_producer(), gwthread_wakeup(), incoming_wdp, incoming_wdp_counter, is_allowed_ip(), isolated, MAIN_THREAD_ID, msg_create, octstr_destroy(), octstr_get_cstr, read_available(), udp_get_ip(), udp_get_port(), udp_recvfrom(), Udpc, warning(), and wdp_datagram.

Referenced by add_service().

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     /* remove messages from socket until it is closed */
00136     while (bb_status != BB_DEAD && bb_status != BB_SHUTDOWN) {
00137 
00138     gwlist_consume(isolated);   /* block here if suspended/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         /* No datagram available, don't block. */
00147         continue;
00148 
00149         error(errno, "Failed to receive an UDP");
00150         /*
00151          * just continue, or is there ANY error that would result
00152          * in situation where it would be better to break; or even
00153          * die off?     - Kalle 28.2
00154          */
00155         continue;
00156     }
00157 
00158     /* discard the message if the client is not allowed */
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 }

Here is the call graph for this function:

void udp_sender void *  arg  )  [static]
 

Definition at line 205 of file bb_udp.c.

References bb_status, counter_increase(), debug(), _udpc::fd, flow_threads, gwlist_add_producer(), gwlist_consume(), gwlist_remove_producer(), gwthread_join(), msg_destroy(), _udpc::outgoing_list, outgoing_wdp_counter, _udpc::receiver, send_udp(), suspended, Udpc, and udpc_destroy().

Referenced by add_service().

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);  /* block here if 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         /* ok, we failed... tough
00222          * XXX log the message or something like that... but this
00223          * is not as fatal as it is with SMS-messages...
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 }

Here is the call graph for this function:

int udp_shutdown void   ) 
 

Definition at line 424 of file bb_udp.c.

References debug(), gwlist_remove_producer(), and incoming_wdp.

Referenced by bb_shutdown(), and main().

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 }

Here is the call graph for this function:

int udp_start Cfg cfg  ) 
 

Definition at line 323 of file bb_udp.c.

References add_service(), allow_ip, cfg_get, cfg_get_single_group(), debug(), deny_ip, error(), gwlist_add_producer(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_len(), incoming_wdp, info(), octstr_destroy(), octstr_get_cstr, octstr_imm(), octstr_split(), udp_running, and udpc_list.

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     /*  we'll activate WTLS as soon as we have a 'wtls' config group */
00345     grp = cfg_get_single_group(cfg, octstr_imm("wtls"));
00346     allow_wtls = grp != NULL ? 1 : 0;
00347 
00348     udpc_list = gwlist_create();    /* have a list of running systems */
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));   /* wsp     */
00356         add_service(9201, octstr_get_cstr(iface));   /* wsp/wtp */
00357     
00358 #ifdef HAVE_WTLS_OPENSSL
00359         if (allow_wtls) {
00360              add_service(9202, octstr_get_cstr(iface));   /* wsp/wtls   */
00361              add_service(9203, octstr_get_cstr(iface));   /* wsp/wtp/wtls */
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     /* add_service(9204, octstr_get_cstr(interface_name));  * vcard */
00368     /* add_service(9205, octstr_get_cstr(interface_name));  * vcal  */
00369     /* add_service(9206, octstr_get_cstr(interface_name));  * vcard/wtls */
00370     /* add_service(9207, octstr_get_cstr(interface_name));  * vcal/wtls */
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 }

Here is the call graph for this function:

Udpc* udpc_create int  port,
char *  interface_name
[static]
 

Definition at line 242 of file bb_udp.c.

References _udpc::addr, debug(), error(), _udpc::fd, gwlist_create, octstr_create, octstr_destroy(), octstr_get_cstr, _udpc::outgoing_list, port, udp_bind(), udp_create_address(), udp_get_ip(), udp_get_port(), and Udpc.

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 }    

Here is the call graph for this function:

void udpc_destroy Udpc udpc  )  [static]
 

Definition at line 277 of file bb_udp.c.

References _udpc::addr, _udpc::fd, gw_assert, gwlist_destroy(), gwlist_len(), octstr_destroy(), _udpc::outgoing_list, and 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 }    

Here is the call graph for this function:


Variable Documentation

Octstr* allow_ip [static]
 

Definition at line 111 of file bb_udp.c.

Referenced by udp_die(), udp_receiver(), and udp_start().

volatile sig_atomic_t bb_status
 

Definition at line 120 of file bearerbox.c.

Octstr* deny_ip [static]
 

Definition at line 112 of file bb_udp.c.

Referenced by udp_die(), udp_receiver(), and udp_start().

List* flow_threads
 

Definition at line 107 of file bearerbox.c.

List* incoming_wdp
 

Definition at line 86 of file bearerbox.c.

Counter* incoming_wdp_counter
 

Definition at line 91 of file bearerbox.c.

Referenced by bb_print_status(), empty_msg_lists(), init_bearerbox(), main(), and udp_receiver().

List* isolated
 

Definition at line 118 of file bearerbox.c.

Counter* outgoing_wdp_counter
 

Definition at line 92 of file bearerbox.c.

Referenced by bb_print_status(), empty_msg_lists(), init_bearerbox(), main(), udp_receiver(), and udp_sender().

List* suspended
 

Definition at line 113 of file bearerbox.c.

volatile sig_atomic_t udp_running [static]
 

Definition at line 96 of file bb_udp.c.

Referenced by udp_die(), udp_outgoing_queue(), and udp_start().

List* udpc_list [static]
 

Definition at line 97 of file bb_udp.c.

Referenced by add_service(), udp_addwdp(), udp_die(), udp_outgoing_queue(), and udp_start().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.