From 87bd7a967598e1dbd7c10515939e5b0fb7a45436 Mon Sep 17 00:00:00 2001 From: Cerghit Ionel Date: Thu, 23 Jul 2015 13:34:46 +0300 Subject: [PATCH] Added version field in the header of bin protocol, to avoid compatibility problems between different versions of opensips --- bin_interface.c | 72 ++++++++-------------------- bin_interface.h | 26 ++++------ cfg.lex | 6 --- cfg.y | 27 ----------- modules/dialog/dlg_replication.c | 39 +++++++++++---- modules/dialog/dlg_replication.h | 2 + modules/ratelimit/ratelimit.h | 2 + modules/ratelimit/ratelimit_helper.c | 17 +++++-- modules/usrloc/ureplication.c | 16 +++++-- modules/usrloc/ureplication.h | 2 + pt.c | 1 - 11 files changed, 89 insertions(+), 121 deletions(-) diff --git a/bin_interface.c b/bin_interface.c index 4bfbfa5ef4c..1c47692dc5a 100644 --- a/bin_interface.c +++ b/bin_interface.c @@ -30,8 +30,6 @@ struct socket_info *bin; -int bin_children = 1; - static char *send_buffer; static char *cpos; @@ -40,26 +38,31 @@ static char *rcv_buf; static char *rcv_end; static struct packet_cb_list *reg_modules; - /** * bin_init - begins the construction of a new binary packet (header part): * - * +-------------------+------------------------------------------------------+ - * | 8-byte HEADER | BODY max 65535 bytes | - * +-------------------+------------------------------------------------------+ - * | PK_MARKER | CRC | LEN | MOD_NAME | CMD | LEN | FIELD | LEN | FIELD |...| - * +-------------------+------------------------------------------------------+ + * +-------------------+-----------------------------------------------------------------+ + * | 12-byte HEADER | BODY max 65535 bytes | + * +-------------------+-----------------------------------------------------------------+ + * | PK_MARKER |PGK LEN| Version | LEN | MOD_NAME | CMD | LEN | FIELD | LEN | FIELD |....| + * +-------------------+-----------------------------------------------------------------+ * * @param: { LEN, MOD_NAME } + CMD */ +short get_bin_pkg_version(void) +{ + return *(short *)(rcv_buf + BIN_PACKET_MARKER_SIZE + PKG_LEN_FIELD_SIZE); +} + + void set_len(char *send_buffer, char *cpos){ unsigned short len = cpos - send_buffer, *px; px = (unsigned short *) (send_buffer + BIN_PACKET_MARKER_SIZE); *px = len; } -int bin_init(str *mod_name, int cmd_type) +int bin_init(str *mod_name, int cmd_type, short version) { if (!send_buffer) { send_buffer = pkg_malloc(BUF_SIZE); @@ -69,9 +72,14 @@ int bin_init(str *mod_name, int cmd_type) } } - /* binary packet header: marker + crc */ + /* binary packet header: marker + pkg_len */ memcpy(send_buffer, BIN_PACKET_MARKER, BIN_PACKET_MARKER_SIZE); - cpos = send_buffer + HEADER_SIZE; + cpos = send_buffer + BIN_PACKET_MARKER_SIZE + PKG_LEN_FIELD_SIZE; + + + /* bin version */ + memcpy(cpos, &version, sizeof(version)); + cpos += VERSION_FIELD_SIZE; /* module name */ memcpy(cpos, &mod_name->len, LEN_FIELD_SIZE); @@ -271,46 +279,6 @@ int bin_pop_int(void *info) return 0; } -/** - * bin_send - computes the checksum of the current packet and then - * sends the packet over UDP to the @dest destination - * - * @return: number of bytes sent, or -1 on error - */ -int bin_send(union sockaddr_union *dest) -{ - int rc, destlen; - str st; - char *ip; - unsigned short port; - - if (!dest) - return 0; - - st.s = send_buffer + HEADER_SIZE; - st.len = bin_send_size - HEADER_SIZE; - - /* compute a checksum of the binary packet content */ - crc32_uint(&st, (unsigned int *)(send_buffer + BIN_PACKET_MARKER_SIZE)); - - LM_DBG("sending packet {'%.*s', %d}: %.*s [%d B] from socket %d\n", - *(int *)(send_buffer + HEADER_SIZE), send_buffer + HEADER_SIZE + - LEN_FIELD_SIZE, bin_send_type, bin_send_size, send_buffer, bin_send_size, - bin->socket); - - destlen=sockaddru_len(*dest); -again: - rc=sendto(bin->socket, send_buffer, bin_send_size, 0, &dest->s, destlen); - if (rc==-1){ - if (errno==EINTR) goto again; - get_su_info(&dest->s, ip, port); - LM_ERR("sendto() failed with %s(%d) - destination %s:%hu\n", - strerror(errno), errno, ip, port); - } - - return rc; -} - /** * bin_register_cb - registers a module handler for specific packets * @mod_name: used to classify the incoming packets @@ -348,7 +316,9 @@ int bin_register_cb(char *mod_name, void (*cb)(int, struct receive_info *)) void call_callbacks(char* buffer, struct receive_info *rcv){ str name; struct packet_cb_list *p; + rcv_buf = buffer; + get_name(rcv_buf, name); rcv_end = rcv_buf + *(unsigned short*)(buffer + BIN_PACKET_MARKER_SIZE); diff --git a/bin_interface.h b/bin_interface.h index 2fb4c933ddc..7102ed1f19a 100644 --- a/bin_interface.h +++ b/bin_interface.h @@ -30,10 +30,11 @@ #define BIN_PACKET_MARKER "P4CK" #define BIN_PACKET_MARKER_SIZE 4 -#define CRC_FIELD_SIZE 4 +#define PKG_LEN_FIELD_SIZE 4 +#define VERSION_FIELD_SIZE 4 #define LEN_FIELD_SIZE sizeof(int) #define CMD_FIELD_SIZE sizeof(int) -#define HEADER_SIZE (BIN_PACKET_MARKER_SIZE + CRC_FIELD_SIZE) +#define HEADER_SIZE (BIN_PACKET_MARKER_SIZE + PKG_LEN_FIELD_SIZE + VERSION_FIELD_SIZE) #define MIN_BIN_PACKET_SIZE \ (HEADER_SIZE + LEN_FIELD_SIZE + CMD_FIELD_SIZE + 2) /* e.g. >tm<.so */ @@ -57,9 +58,6 @@ name.s = _p + HEADER_SIZE + LEN_FIELD_SIZE; \ } while (0) -extern struct socket_info *bin; -extern int bin_children; - struct packet_cb_list { str module; /* registered module */ void (*cbf)(int packet_type, /* module callback */ @@ -69,6 +67,11 @@ struct packet_cb_list { }; +/** + returns the version of the bin protocol from the received message +*/ +short get_bin_pkg_version(void); + /** calls all the registered functions @@ -91,7 +94,7 @@ int bin_register_cb(char *mod_name, void (*)(int packet_type, struct receive_inf * * @return: 0 on success */ -int bin_init(str *mod_name, int packet_type); +int bin_init(str *mod_name, int packet_type, short version); /* * adds a new string value to the packet being currently built @@ -162,16 +165,5 @@ int bin_skip_int(int count); */ int bin_skip_str(int count); -/** - * bin_send - computes the checksum of the current packet and then - * sends the packet over UDP to the @dest destination - * - * @return: number of bytes sent, or -1 on error - */ -int bin_send(union sockaddr_union *dest); - -/* at OpenSIPS startup */ -int start_bin_receivers(void); - #endif /* __BINARY_INTERFACE__ */ diff --git a/cfg.lex b/cfg.lex index eec0c453b78..90552807934 100644 --- a/cfg.lex +++ b/cfg.lex @@ -294,8 +294,6 @@ LOGFACILITY log_facility LOGNAME log_name AVP_ALIASES avp_aliases LISTEN listen -BIN_LISTEN bin_listen -BIN_CHILDREN bin_children ALIAS alias AUTO_ALIASES auto_aliases DNS dns @@ -567,10 +565,6 @@ IMPORTFILE "import_file" {LOGNAME} { yylval.strval=yytext; return LOGNAME; } {AVP_ALIASES} { yylval.strval=yytext; return AVP_ALIASES; } {LISTEN} { count(); yylval.strval=yytext; return LISTEN; } -{BIN_CHILDREN} { count(); yylval.strval=yytext; - return BIN_CHILDREN; } -{BIN_LISTEN} { count(); yylval.strval=yytext; - return BIN_LISTEN; } {ALIAS} { count(); yylval.strval=yytext; return ALIAS; } {AUTO_ALIASES} { count(); yylval.strval=yytext; return AUTO_ALIASES; } {DNS} { count(); yylval.strval=yytext; return DNS; } diff --git a/cfg.y b/cfg.y index 6b1fb275a9f..5c54ca5a477 100644 --- a/cfg.y +++ b/cfg.y @@ -306,8 +306,6 @@ extern char *finame; %token LOGNAME %token AVP_ALIASES %token LISTEN -%token BIN_LISTEN -%token BIN_CHILDREN %token ALIAS %token AUTO_ALIASES %token DNS @@ -883,31 +881,6 @@ assign_stm: DEBUG EQUAL snumber { | LISTEN EQUAL error { yyerror("ip address or hostname " "expected (use quotes if the hostname includes" " config keywords)"); } - | BIN_LISTEN EQUAL listen_id COLON port { - // TODO - think it should be remoevd - if (bin) { - yyerror("can only define one binary packet interface"); - YYABORT; - } - - lst_tmp = mk_listen_id($3, PROTO_BIN, $5); - bin = new_sock_info(lst_tmp->name, - lst_tmp->port, - lst_tmp->proto, - lst_tmp->adv_name, - lst_tmp->adv_port, - lst_tmp->children, - 0); - if (!bin) { - LM_CRIT("Failed to create new socket info!\n"); - YYABORT; - } - } - | BIN_LISTEN EQUAL error { yyerror("ip address or hostname " - "expected (use quotes if the hostname includes" - " config keywords)"); } - | BIN_CHILDREN EQUAL NUMBER { bin_children=$3; } - | BIN_CHILDREN EQUAL error { yyerror("number expected"); } | ALIAS EQUAL id_lst { for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) add_alias(lst_tmp->name, strlen(lst_tmp->name), diff --git a/modules/dialog/dlg_replication.c b/modules/dialog/dlg_replication.c index f38495695d8..b5d4fc82fa2 100644 --- a/modules/dialog/dlg_replication.c +++ b/modules/dialog/dlg_replication.c @@ -32,6 +32,7 @@ #include "dlg_repl_profile.h" #include "../../resolve.h" +#include "../../forward.h" extern int active_dlgs_cnt; extern int early_dlgs_cnt; @@ -448,8 +449,10 @@ void replicate_dialog_created(struct dlg_cell *dlg) static str module_name = str_init("dialog"); int callee_leg; str *vars, *profiles; + str send_buffer; - if (bin_init(&module_name, REPLICATION_DLG_CREATED) != 0) + + if (bin_init(&module_name, REPLICATION_DLG_CREATED, BIN_VERSION) != 0) goto error; callee_leg = callee_idx(dlg); @@ -495,8 +498,10 @@ void replicate_dialog_created(struct dlg_cell *dlg) bin_push_int(dlg->legs[DLG_CALLER_LEG].last_gen_cseq); bin_push_int(dlg->legs[callee_leg].last_gen_cseq); + bin_get_buffer(&send_buffer); + for (d = replication_dests; d; d = d->next) - bin_send(&d->to); + msg_send(0,PROTO_BIN,&d->to,0,send_buffer.s,send_buffer.len,0); if_update_stat(dlg_enable_stats,create_sent,1); return; @@ -515,8 +520,9 @@ void replicate_dialog_updated(struct dlg_cell *dlg) static str module_name = str_init("dialog"); int callee_leg; str *vars, *profiles; + str send_buffer; - if (bin_init(&module_name, REPLICATION_DLG_UPDATED) != 0) + if (bin_init(&module_name, REPLICATION_DLG_UPDATED, BIN_VERSION) != 0) goto error; callee_leg = callee_idx(dlg); @@ -562,8 +568,10 @@ void replicate_dialog_updated(struct dlg_cell *dlg) bin_push_int(dlg->legs[DLG_CALLER_LEG].last_gen_cseq); bin_push_int(dlg->legs[callee_leg].last_gen_cseq); + bin_get_buffer(&send_buffer); + for (d = replication_dests; d; d = d->next) - bin_send(&d->to); + msg_send(0,PROTO_BIN,&d->to,0,send_buffer.s,send_buffer.len,0); if_update_stat(dlg_enable_stats,update_sent,1); return; @@ -580,16 +588,19 @@ void replicate_dialog_deleted(struct dlg_cell *dlg) { struct replication_dest *d; static str module_name = str_init("dialog"); + str send_buffer; - if (bin_init(&module_name, REPLICATION_DLG_DELETED) != 0) + if (bin_init(&module_name, REPLICATION_DLG_DELETED, BIN_VERSION) != 0) goto error; bin_push_str(&dlg->callid); bin_push_str(&dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&dlg->legs[callee_idx(dlg)].tag); + bin_get_buffer(&send_buffer); + for (d = replication_dests; d; d = d->next) - bin_send(&d->to); + msg_send(0,PROTO_BIN,&d->to,0,send_buffer.s,send_buffer.len,0); if_update_stat(dlg_enable_stats,delete_sent,1); return; @@ -609,6 +620,11 @@ void receive_binary_packet(int packet_type, struct receive_info *ri) LM_DBG("Received a binary packet!\n"); + if(get_bin_pkg_version() != BIN_VERSION){ + LM_ERR("incompatible bin protocol version\n"); + return; + } + if (accept_repl_profiles && packet_type == REPLICATION_DLG_PROFILE) { /* TODO: handle this */ dlg_replicated_profiles(ri); @@ -782,9 +798,12 @@ int repl_prof_dest(modparam_t type, void *val) static inline void dlg_replicate_profiles(void) { unsigned i; + str send_buffer; + + bin_get_buffer(&send_buffer); for (i = 0; i < repl_prof_dests_nr; i++) - bin_send(&repl_prof_dests[i].to); + msg_send(0,PROTO_BIN,&repl_prof_dests[i].to,0,send_buffer.s,send_buffer.len,0); } static void dlg_replicated_profiles(struct receive_info *ri) @@ -930,7 +949,7 @@ int repl_prof_remove(str *name, str *value) static str module_name = str_init("dialog"); if (!repl_prof_dests_nr) return 0; - if (bin_init(&module_name, REPLICATION_DLG_PROFILE) < 0) { + if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { LM_ERR("cannot initiate bin buffer\n"); return -1; } @@ -1022,7 +1041,7 @@ static void repl_prof_utimer_f(utime_t ticks, void *param) dlg_replicate_profiles(); \ LM_DBG("sent %d records\n", nr); \ } \ - if (bin_init(&module_name, REPLICATION_DLG_PROFILE) < 0) { \ + if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { \ LM_ERR("cannot initiate bin buffer\n"); \ return; \ } \ @@ -1040,7 +1059,7 @@ static void repl_prof_utimer_f(utime_t ticks, void *param) void **dst; str *value; - if (bin_init(&module_name, REPLICATION_DLG_PROFILE) < 0) { + if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } diff --git a/modules/dialog/dlg_replication.h b/modules/dialog/dlg_replication.h index faca1722cde..948b80f0612 100644 --- a/modules/dialog/dlg_replication.h +++ b/modules/dialog/dlg_replication.h @@ -36,6 +36,8 @@ #define REPLICATION_DLG_UPDATED 2 #define REPLICATION_DLG_DELETED 3 +#define BIN_VERSION 1 + extern int accept_replicated_dlg; extern struct replication_dest *replication_dests; diff --git a/modules/ratelimit/ratelimit.h b/modules/ratelimit/ratelimit.h index 6ec1013536a..82b5f3999f3 100644 --- a/modules/ratelimit/ratelimit.h +++ b/modules/ratelimit/ratelimit.h @@ -30,6 +30,8 @@ #define RL_HASHSIZE 1024 #define RL_TIMER_INTERVAL 10 #define RL_PIPE_PENDING (1<<0) +#define BIN_VERSION 1 + #include "../../map.h" diff --git a/modules/ratelimit/ratelimit_helper.c b/modules/ratelimit/ratelimit_helper.c index bb458df811e..edeffde2931 100644 --- a/modules/ratelimit/ratelimit_helper.c +++ b/modules/ratelimit/ratelimit_helper.c @@ -1,4 +1,4 @@ -/* +/*: * Copyright (C) 2011 OpenSIPS Solutions * * This file is part of opensips, a free SIP server. @@ -34,6 +34,7 @@ #include "../../cachedb/cachedb.h" #include "../../cachedb/cachedb_cap.h" +#include "../../forward.h" #include #include @@ -751,6 +752,11 @@ void rl_rcv_bin(int packet_type, struct receive_info *ri) unsigned int hash_idx; time_t now; + if(get_bin_pkg_version() != BIN_VERSION){ + LM_ERR("incompatible bin protocol version\n"); + return; + } + if (packet_type != RL_PIPE_COUNTER) return; @@ -917,9 +923,12 @@ int rl_add_repl_dst(modparam_t type, void *val) static inline void rl_replicate(void) { unsigned i; + str send_buffer; + + bin_get_buffer(&send_buffer); for (i = 0; i < rl_dests_nr; i++) - bin_send(&rl_dests[i].to); + msg_send(0,PROTO_BIN,&rl_dests[i].to,0,send_buffer.s,send_buffer.len,0); } void rl_timer_repl(utime_t ticks, void *param) @@ -932,7 +941,7 @@ void rl_timer_repl(utime_t ticks, void *param) int nr = 0; int ret; - if (bin_init(&module_name, RL_PIPE_COUNTER) < 0) { + if (bin_init(&module_name, RL_PIPE_COUNTER, BIN_VERSION) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } @@ -978,7 +987,7 @@ void rl_timer_repl(utime_t ticks, void *param) /* send the buffer */ if (nr) rl_replicate(); - if (bin_init(&module_name, RL_PIPE_COUNTER) < 0) { + if (bin_init(&module_name, RL_PIPE_COUNTER, BIN_VERSION) < 0) { LM_ERR("cannot initiate bin buffer\n"); RL_RELEASE_LOCK(i); return; diff --git a/modules/usrloc/ureplication.c b/modules/usrloc/ureplication.c index 081a3b80528..6487fe0df89 100644 --- a/modules/usrloc/ureplication.c +++ b/modules/usrloc/ureplication.c @@ -40,7 +40,7 @@ void replicate_urecord_insert(urecord_t *r) struct replication_dest *d; str send_buffer; - if (bin_init(&repl_module_name, REPL_URECORD_INSERT) != 0) { + if (bin_init(&repl_module_name, REPL_URECORD_INSERT, BIN_VERSION) != 0) { LM_ERR("failed to replicate this event\n"); return; } @@ -59,7 +59,7 @@ void replicate_urecord_delete(urecord_t *r) struct replication_dest *d; str send_buffer; - if (bin_init(&repl_module_name, REPL_URECORD_DELETE) != 0) { + if (bin_init(&repl_module_name, REPL_URECORD_DELETE, BIN_VERSION) != 0) { LM_ERR("failed to replicate this event\n"); return; } @@ -79,7 +79,7 @@ void replicate_ucontact_insert(urecord_t *r, str *contact, ucontact_info_t *ci) str send_buffer; str st; - if (bin_init(&repl_module_name, REPL_UCONTACT_INSERT) != 0) { + if (bin_init(&repl_module_name, REPL_UCONTACT_INSERT, BIN_VERSION) != 0) { LM_ERR("failed to replicate this event\n"); return; } @@ -124,7 +124,7 @@ void replicate_ucontact_update(urecord_t *r, str *contact, ucontact_info_t *ci) str send_buffer; str st; - if (bin_init(&repl_module_name, REPL_UCONTACT_UPDATE) != 0) { + if (bin_init(&repl_module_name, REPL_UCONTACT_UPDATE, BIN_VERSION) != 0) { LM_ERR("failed to replicate this event\n"); return; } @@ -168,7 +168,7 @@ void replicate_ucontact_delete(urecord_t *r, ucontact_t *c) struct replication_dest *d; str send_buffer; - if (bin_init(&repl_module_name, REPL_UCONTACT_DELETE) != 0) { + if (bin_init(&repl_module_name, REPL_UCONTACT_DELETE, BIN_VERSION) != 0) { LM_ERR("failed to replicate this event\n"); return; } @@ -544,6 +544,12 @@ void receive_binary_packet(int packet_type, struct receive_info *ri) LM_DBG("received a binary packet [%d]!\n", packet_type); + if(get_bin_pkg_version() != BIN_VERSION){ + LM_ERR("incompatible bin protocol version\n"); + return; + } + + switch (packet_type) { case REPL_URECORD_INSERT: rc = receive_urecord_insert(); diff --git a/modules/usrloc/ureplication.h b/modules/usrloc/ureplication.h index b294ea7e82a..294e290864b 100644 --- a/modules/usrloc/ureplication.h +++ b/modules/usrloc/ureplication.h @@ -41,6 +41,8 @@ #define REPL_UCONTACT_UPDATE 4 #define REPL_UCONTACT_DELETE 5 +#define BIN_VERSION 1 + extern int accept_replicated_udata; extern struct replication_dest *replication_dests; extern str repl_module_name; diff --git a/pt.c b/pt.c index a463333d722..9e56533c714 100644 --- a/pt.c +++ b/pt.c @@ -64,7 +64,6 @@ int init_multi_proc_support(void) } /* info packet UDP receivers */ - proc_no += bin ? bin_children : 0; /* timer processes */ proc_no += 2 /* timer keeper + timer trigger */;