#include <sys/types.h>#include <sys/socket.h>#include <netinet/tcp.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/poll.h>#include <signal.h>#include <time.h>#include <sys/wait.h>#include "../../ip_addr.h"#include "../../hash_func.h"#include "../../mem/mem.h"#include "../../mem/shm_mem.h"#include "../../dprint.h"#include "../../locking.h"#include "seas.h"#include "ha.h"#include "cluster.h"#include "seas_action.h"#include "statistics.h"#include "event_dispatcher.h"

Go to the source code of this file.
Data Structures | |
| union | helper |
Defines | |
| #define | MAX_WRITE_TRIES 10 |
| #define | PING_OVER_FACTOR 2 |
Functions | |
| static int | add_new_as (int event_idx, int action_idx, struct as_entry *as) |
| static int | dispatch_relay () |
| int | dispatcher_main_loop (void) |
| static int | handle_as_data (int fd) |
| static int | handle_unc_as_data (int fd) |
| static int | new_as_connect (int fd, char which) |
| static int | open_server_sockets (struct ip_addr *address, unsigned short port, int *fd) |
| static int | print_sock_info (char *buffer, int wheremax, int *idx, struct socket_info *s, enum sip_protos type) |
| int | process_bind_action (as_p as, char *payload, int len) |
| static int | process_event_reply (as_p as) |
| int | process_unbind_action (as_p as, char *payload, int len) |
| static int | read_name (int sock, char *dst, int dstlen) |
| static int | send_sockinfo (int fd) |
| int | spawn_action_dispatcher (struct as_entry *the_as) |
Variables | |
| char * | action_names [] |
| struct as_entry * | my_as |
| int | process_no |
| int | sig_flag |
| struct unc_as | unc_as_t [2 *MAX_UNC_AS_NR] |
| #define MAX_WRITE_TRIES 10 |
| #define PING_OVER_FACTOR 2 |
| static int add_new_as | ( | int | event_idx, | |
| int | action_idx, | |||
| struct as_entry * | as | |||
| ) | [inline, static] |
receives 2 indexes in unc_as_t which correspond one to the events socket and the other to the actions socket
returns 0 on success -1 on error
Definition at line 517 of file event_dispatcher.c.
References app_server::action_fd, app_server::action_pid, as_entry::as, AS_BUF_SIZE, as_list, cluster::as_names, AS_TYPE, as_entry::connected, as_entry::cs, destroy_pingtable(), app_server::ev_buffer, app_server::event_fd, unc_as::fd, init_pingtable(), jain_ping_period, jain_ping_timeout, app_server::jain_pings, _str::len, LM_ERR, as_entry::name, unc_as::name, app_server::name, as_entry::next, cluster::num, PING_OVER_FACTOR, pkg_free, pkg_malloc, cluster::registered, _str::s, send_sockinfo(), servlet_ping_period, servlet_ping_timeout, app_server::servlet_pings, spawn_action_dispatcher(), as_entry::type, as_entry::u, unc_as_t, and use_ha.
Referenced by handle_unc_as_data().
| static int dispatch_relay | ( | void | ) | [static] |
Sends event
returns 0 OK -1 couldn't read the event from the pipe -2 couldn't send the event TODO this should be FAR more generic... for example, there might be events which are not related to any transaction (finish event, or error event...) we should separate event-specific handling in different functions...
Definition at line 418 of file event_dispatcher.c.
References action_names, as_entry::as, as_msg::as, helper::bytes, CLUSTER_TYPE, as_entry::connected, app_server::event_fd, event_stat(), len, _str::len, as_msg::len, LM_DBG, LM_ERR, LM_WARN, MAX_WRITE_TRIES, as_msg::msg, app_server::name, NULL, helper::ptr, read_pipe, _str::s, shm_free, as_msg::transaction, as_msg::type, as_entry::type, as_entry::u, and use_stats.
Referenced by dispatcher_main_loop().
| int dispatcher_main_loop | ( | void | ) |
Main loop for the Event Dispatcher process.
we decrement i so that pulling down the upper part of the unc_as array so that it doesn't affect our for loop
Definition at line 86 of file event_dispatcher.c.
References app_server::action_fd, app_server::action_pid, as_entry::as, as_list, AS_TYPE, CLUSTER_TYPE, as_entry::connected, destroy_pingtable(), dispatch_relay(), app_server::ev_buffer, app_server::event_fd, handle_as_data(), handle_unc_as_data(), is_dispatcher, app_server::jain_pings, _str::len, LM_DBG, LM_ERR, LM_INFO, LM_WARN, as_entry::name, new_as_connect(), as_entry::next, open_server_sockets(), pkg_free, process_no, read_pipe, _str::s, seas_listen_ip, seas_listen_port, seas_sighandler(), app_server::servlet_pings, sig_flag, spawn_pinger(), as_entry::type, as_entry::u, use_ha, and whoami.
Referenced by seas_child_init().
| static int handle_as_data | ( | int | fd | ) | [static] |
Handles data from an AppServer. First searches in the AS table which was the AS that sent the data (we dont already know it because this comes from a poll_fd struct). When the one is found, it calls process_event_reply, which in turn looks if there's a complete event in the buffer, and if there is, processes it.
returns -1 on error -2 on read()==0 (the socket has been closed by the other end) 0 on success
Definition at line 708 of file event_dispatcher.c.
References as_entry::as, AS_BUF_SIZE, as_list, AS_TYPE, as_entry::connected, app_server::ev_buffer, app_server::event_fd, _str::len, LM_DBG, LM_ERR, as_entry::name, as_entry::next, process_event_reply(), _str::s, as_entry::type, and as_entry::u.
Referenced by dispatcher_main_loop().
| static int handle_unc_as_data | ( | int | fd | ) | [static] |
params: the filedes where the data was received. returns: 0 if this fd should be taken out of the poll_fd array bcause it already has AS name. fd if an AS was completed (returns the fd of the events socket) -1 if there was an error -2 if client disconnected and should be closed and taken outside the poll_fd array
Definition at line 909 of file event_dispatcher.c.
References add_new_as(), as_entry::as, as_list, as_entry::connected, unc_as::fd, unc_as::flags, HAS_NAME, _str::len, len, LM_DBG, LM_ERR, LM_INFO, LM_WARN, MAX_AS_NAME, MAX_UNC_AS_NR, unc_as::name, as_entry::name, as_entry::next, read_name(), _str::s, unc_as_t, and unc_as::valid.
Referenced by dispatcher_main_loop().
| static int new_as_connect | ( | int | fd, | |
| char | which | |||
| ) | [static] |
Definition at line 1039 of file event_dispatcher.c.
References unc_as::fd, unc_as::flags, HAS_FD, LM_ERR, LM_WARN, MAX_UNC_AS_NR, sockaddr_union::s, sock, unc_as_t, and unc_as::valid.
Referenced by dispatcher_main_loop().
| static int open_server_sockets | ( | struct ip_addr * | address, | |
| unsigned short | port, | |||
| int * | fd | |||
| ) | [static] |
opens the server socket, which attends (accepts) the clients, that is: params: address: address to which to listen port: base port to which to listen. then port+1 will be the socket for action's delivery. fds: in fd[0] the action socket will be put. in fd[1] the event socket will be put.
returns 0 on exit, <0 on fail
Definition at line 353 of file event_dispatcher.c.
References ip_addr::af, AF2PF, init_su(), LM_ERR, and sockaddr_union::s.
Referenced by dispatcher_main_loop().
| static int print_sock_info | ( | char * | buffer, | |
| int | wheremax, | |||
| int * | idx, | |||
| struct socket_info * | s, | |||
| enum sip_protos | type | |||
| ) | [inline, static] |
Definition at line 670 of file event_dispatcher.c.
References socket_info::address_str, _str::len, LM_ERR, socket_info::name, socket_info::port_no, and _str::s.
Referenced by send_sockinfo().
| int process_bind_action | ( | as_p | as, | |
| char * | payload, | |||
| int | len | |||
| ) |
processes a BIND event type from the AS. Bind events follow this form: 4:flags 1:processor_id 1:Address Family 1:address length in bytes (16 for ipv6, 4 for ipv4) in NETWORK BYTE ORDER (fortunately, ip_addr struct stores it in NBO) [16|4]:the IP address 1:protocol used (UDP,TCP or TLS); 2:NBO port
Definition at line 804 of file event_dispatcher.c.
References ip_addr::addr, socket_info::address, ip_addr::af, app_server::binds, app_server::bound_processor, ip_addr::len, LM_DBG, LM_ERR, MAX_BINDS, net2hostL, socket_info::next, app_server::num_binds, port, socket_info::port_no, print_ip_buf(), PROTO_TCP, PROTO_TLS, PROTO_UDP, ip_addr::u, and udp_listen.
Referenced by process_event_reply().
| static int process_event_reply | ( | as_p | as | ) | [static] |
This function processess the Application Server buffer. We do buffered processing because it increases performance quite a bit. Any message sent from the AS comes with the first 2 bytes as an NBO unsigned short int which says the length of the following message (header and payload). This way, we avoid multiple small reads() to the socket, which (as we know), consumes far more processor because of the kernel read(2) system call. The drawback is the added complexity of mantaining a buffer, the bytes read, and looking if there is a complete message already prepared.
Actions are supposed to be small, that's why BUF_SIZE is 2000 bytes length. Most of the actions will be that size or less. That is why the 4 bytes telling the length of the Action payload are included in its size. This way you can use a fixed size buffer to receive the Actions and not need to be pkb_malloc'ing for each new event. If there is a particular bigger packet, for example one carrying a picture (a JPG can easily surpass the 2000 byte limit) then a pkg_malloc will be required. This is left TODO
returns -1 on error (packet too big) 0 on success
Definition at line 759 of file event_dispatcher.c.
References AS_BUF_SIZE, BIND_AC, app_server::ev_buffer, _str::len, LM_DBG, LM_WARN, app_server::name, process_bind_action(), process_unbind_action(), _str::s, and UNBIND_AC.
Referenced by handle_as_data().
| int process_unbind_action | ( | as_p | as, | |
| char * | payload, | |||
| int | len | |||
| ) |
processes a UNBIND event type from the AS. Bind events follow this form: 1:processor_id
Definition at line 878 of file event_dispatcher.c.
References app_server::bound_processor, LM_DBG, LM_ERR, MAX_BINDS, net2hostL, and app_server::num_binds.
Referenced by process_event_reply().
| static int read_name | ( | int | sock, | |
| char * | dst, | |||
| int | dstlen | |||
| ) | [inline, static] |
Definition at line 990 of file event_dispatcher.c.
References LM_ERR, and LM_WARN.
Referenced by handle_unc_as_data().
| static int send_sockinfo | ( | int | fd | ) | [inline, static] |
prints available sockets in SER to the App Server. format is: 1: transport identifier (u for UDP, t for TCP, s for TLS) 1: length of socket name (sip.voztele.com or whatever) N: name 1: length of IP address (192.168.1.2) N: ip address in ascii 2: port nubmer in NBO
returns -1 on error 0 on success
Definition at line 612 of file event_dispatcher.c.
References LM_ERR, socket_info::next, print_sock_info(), PROTO_TCP, PROTO_TLS, PROTO_UDP, s, and udp_listen.
Referenced by add_new_as().
| int spawn_action_dispatcher | ( | struct as_entry * | the_as | ) |
Definition at line 1096 of file event_dispatcher.c.
References app_server::action_pid, as_entry::as, dispatch_actions(), is_dispatcher, _str::len, LM_ERR, as_entry::name, pid, _str::s, and as_entry::u.
Referenced by add_new_as().
| char* action_names[] |
Definition at line 66 of file event_dispatcher.c.
Referenced by ac_cancel(), ac_uac_req(), as_action_fail_resp(), dispatch_actions(), process_input(), seas_sighandler(), and spawn_pinger().
| int process_no |
process number - 0 is the main process
Definition at line 298 of file main.c.
Referenced by dispatcher_main_loop(), internal_fork(), my_pid(), and set_proc_attrs().
Definition at line 63 of file event_dispatcher.c.
Referenced by add_new_as(), handle_unc_as_data(), new_as_connect(), and seas_init().
1.5.6