Skip to content

Commit 07774e9

Browse files
Add support for BIN over TLS using the wolfssl library
The actual TLS operations required by the proto_bins module are provided by a wolfssl module which includes the wolfssl library code.
1 parent de8a5dd commit 07774e9

26 files changed

+2472
-154
lines changed

.github/workflows/main.yml

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
steps:
4545
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
4646
- uses: actions/checkout@v2
47+
with:
48+
submodules: recursive
4749

4850
- name: before_install
4951
run: sh -x scripts/build/install_depends.sh

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "modules/wolfssl/lib/wolfssl"]
2+
path = modules/wolfssl/lib/wolfssl
3+
url = [email protected]:wolfSSL/wolfssl.git

Makefile.rules

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ all_misclibs=reg
2222
all_misclibs:=$(addprefix lib/, $(all_misclibs))
2323

2424
#implicit rules
25-
%.o: %.c $(ALLDEP)
25+
%.o: %.c $(ALLDEP) $(DEPS)
2626
ifeq (,$(FASTER))
2727
@echo "Compiling $<"
2828
endif

ip_addr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
enum sip_protos { PROTO_NONE = 0, PROTO_FIRST = 1, PROTO_UDP = 1, \
5959
PROTO_TCP, PROTO_TLS, PROTO_SCTP, PROTO_WS, PROTO_WSS, PROTO_BIN,
60-
PROTO_HEP_UDP, PROTO_HEP_TCP, PROTO_SMPP, PROTO_OTHER };
60+
PROTO_BINS, PROTO_HEP_UDP, PROTO_HEP_TCP, PROTO_SMPP, PROTO_OTHER };
6161
#define PROTO_LAST PROTO_OTHER
6262

6363
struct ip_addr{

modules/clusterer/clusterer.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ static int msg_send_retry(bin_packet_t *packet, node_info_t *dest,
219219
}
220220
bin_get_buffer(packet, &send_buffer);
221221

222-
if (msg_send(chosen_dest->cluster->send_sock, clusterer_proto,
222+
if (msg_send(chosen_dest->cluster->send_sock, chosen_dest->proto,
223223
&chosen_dest->addr, 0, send_buffer.s, send_buffer.len, 0) < 0) {
224224
LM_ERR("msg_send() to node [%d] failed\n", chosen_dest->node_id);
225225
retr_send = 1;
@@ -1026,7 +1026,7 @@ void bin_rcv_cl_packets(bin_packet_t *packet, int packet_type,
10261026
LM_INFO("Received message with unknown source id [%d]\n", source_id);
10271027
if (!db_mode)
10281028
handle_internal_msg_unknown(packet, cl, packet_type, &ri->src_su,
1029-
source_id);
1029+
ri->proto, source_id);
10301030
} else {
10311031
if (!su_ip_cmp(&ri->src_su, &node->addr)) {
10321032
LM_WARN("Received message from unknown source, addr: %s\n", ip);
@@ -1281,7 +1281,7 @@ int send_single_cap_update(cluster_info_t *cluster, struct local_cap *cap,
12811281
bin_get_buffer(&packet, &bin_buffer);
12821282

12831283
for (i = 0; i < no_dests; i++)
1284-
if (msg_send(cluster->send_sock, clusterer_proto,
1284+
if (msg_send(cluster->send_sock, destinations[i]->proto,
12851285
&destinations[i]->addr, 0, bin_buffer.s, bin_buffer.len, 0) < 0) {
12861286
LM_ERR("Failed to send capability update to node [%d]\n",
12871287
destinations[i]->node_id);
@@ -1364,7 +1364,7 @@ int send_cap_update(node_info_t *dest_node, int require_reply)
13641364
bin_push_int(&packet, current_id);
13651365
bin_get_buffer(&packet, &bin_buffer);
13661366

1367-
if (msg_send(dest_node->cluster->send_sock, clusterer_proto, &dest_node->addr,
1367+
if (msg_send(dest_node->cluster->send_sock, dest_node->proto, &dest_node->addr,
13681368
0, bin_buffer.s, bin_buffer.len, 0) < 0) {
13691369
LM_ERR("Failed to send capability update to node [%d]\n", dest_node->node_id);
13701370
set_link_w_neigh_adv(-1, LS_RESTART_PINGING, dest_node);

modules/clusterer/clusterer_mod.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ static module_dependency_t *get_deps_db_mode(param_export_t *param)
232232

233233
static dep_export_t deps = {
234234
{ /* OpenSIPS module dependencies */
235-
{ MOD_TYPE_DEFAULT, "proto_bin", DEP_ABORT },
235+
{ MOD_TYPE_DEFAULT, "proto_bin", DEP_SILENT },
236+
{ MOD_TYPE_DEFAULT, "proto_bins", DEP_SILENT },
236237
{ MOD_TYPE_NULL, NULL, 0 },
237238
},
238239
{ /* modparam dependencies */

modules/clusterer/node_info.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,15 @@ int add_node_info(node_info_t **new_info, cluster_info_t **cl_list, int *int_val
188188
st.len = hlen;
189189

190190
if (proto == PROTO_NONE)
191-
proto = clusterer_proto;
192-
if (proto != clusterer_proto) {
193-
LM_ERR("Clusterer currently supports only BIN protocol, but node: %d "
194-
"has proto=%d\n", int_vals[INT_VALS_NODE_ID_COL], proto);
191+
proto = PROTO_BIN;
192+
else if (proto != PROTO_BIN && proto != PROTO_BINS) {
193+
LM_ERR("Clusterer currently supports only BIN/BINS protocols, but node: "
194+
"%d has proto=%d\n", int_vals[INT_VALS_NODE_ID_COL], proto);
195195
return 1;
196196
}
197197

198+
(*new_info)->proto = proto;
199+
198200
if (int_vals[INT_VALS_NODE_ID_COL] != current_id) {
199201
he = sip_resolvehost(&st, (unsigned short *) &port,
200202
(unsigned short *)&proto, 0, 0);

modules/clusterer/node_info.h

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct node_info {
7070
str description;
7171
str url;
7272
union sockaddr_union addr;
73+
enum sip_protos proto;
7374
str sip_addr;
7475
int priority; /* priority to be chosen as next hop for same length paths */
7576
int no_ping_retries; /* maximum number of ping retries */

modules/clusterer/topology.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static int send_ping(node_info_t *node, int req_node_list)
5757
set_proc_log_level(L_INFO);
5858
#endif
5959

60-
rc = msg_send(node->cluster->send_sock, clusterer_proto, &node->addr, 0,
60+
rc = msg_send(node->cluster->send_sock, node->proto, &node->addr, 0,
6161
send_buffer.s, send_buffer.len, 0);
6262

6363
#ifndef CLUSTERER_EXTRA_BIN_DBG
@@ -487,8 +487,8 @@ int flood_message(bin_packet_t *packet, cluster_info_t *cluster,
487487
lock_release(cluster->current_node->lock);
488488

489489
for (i = 0; i < no_dests; i++) {
490-
if (msg_send(cluster->send_sock, clusterer_proto, &destinations[i]->addr,
491-
0, bin_buffer.s, bin_buffer.len, 0) < 0) {
490+
if (msg_send(cluster->send_sock, destinations[i]->proto,
491+
&destinations[i]->addr, 0, bin_buffer.s, bin_buffer.len, 0) < 0) {
492492
LM_ERR("Failed to flood message to node [%d]\n",
493493
destinations[i]->node_id);
494494

@@ -601,7 +601,7 @@ static int send_full_top_update(node_info_t *dest_node, int nr_nodes, int *node_
601601
bin_push_int(&packet, current_id);
602602
bin_get_buffer(&packet, &bin_buffer);
603603

604-
if (msg_send(dest_node->cluster->send_sock, clusterer_proto, &dest_node->addr,
604+
if (msg_send(dest_node->cluster->send_sock, dest_node->proto, &dest_node->addr,
605605
0, bin_buffer.s, bin_buffer.len, 0) < 0) {
606606
LM_ERR("Failed to send topology update to node [%d]\n", dest_node->node_id);
607607
set_link_w_neigh_adv(-1, LS_RESTART_PINGING, dest_node);
@@ -662,7 +662,7 @@ static int send_ls_update(node_info_t *node, clusterer_link_state new_ls)
662662

663663
bin_get_buffer(&packet, &send_buffer);
664664
for (i = 0; i < no_dests; i++) {
665-
if (msg_send(destinations[i]->cluster->send_sock, clusterer_proto,
665+
if (msg_send(destinations[i]->cluster->send_sock, destinations[i]->proto,
666666
&destinations[i]->addr, 0, send_buffer.s, send_buffer.len, 0) < 0) {
667667
LM_ERR("Failed to send link state update to node [%d]\n",
668668
destinations[i]->node_id);
@@ -1144,7 +1144,7 @@ void handle_full_top_update(bin_packet_t *packet, node_info_t *source,
11441144
}
11451145

11461146
void handle_internal_msg_unknown(bin_packet_t *received, cluster_info_t *cl,
1147-
int packet_type, union sockaddr_union *src_su, int src_node_id)
1147+
int packet_type, union sockaddr_union *src_su, int proto, int src_node_id)
11481148
{
11491149
str bin_buffer;
11501150
int req_list;
@@ -1166,7 +1166,7 @@ void handle_internal_msg_unknown(bin_packet_t *received, cluster_info_t *cl,
11661166
bin_push_int(&packet, current_id);
11671167
bin_get_buffer(&packet, &bin_buffer);
11681168

1169-
if (msg_send(cl->send_sock, clusterer_proto, src_su, 0, bin_buffer.s,
1169+
if (msg_send(cl->send_sock, proto, src_su, 0, bin_buffer.s,
11701170
bin_buffer.len, 0) < 0)
11711171
LM_ERR("Failed to reply to ping from unknown node, id [%d]\n", src_node_id);
11721172
else
@@ -1269,7 +1269,7 @@ void handle_unknown_id(node_info_t *src_node)
12691269
bin_push_int(&packet, current_id);
12701270

12711271
bin_get_buffer(&packet, &bin_buffer);
1272-
if (msg_send(src_node->cluster->send_sock, clusterer_proto, &src_node->addr,
1272+
if (msg_send(src_node->cluster->send_sock, src_node->proto, &src_node->addr,
12731273
0, bin_buffer.s, bin_buffer.len, 0) < 0)
12741274
LM_ERR("Failed to send node description to node [%d]\n", src_node->node_id);
12751275
else
@@ -1316,7 +1316,7 @@ void handle_ping(bin_packet_t *received, node_info_t *src_node,
13161316
set_proc_log_level(L_INFO);
13171317
#endif
13181318

1319-
send_rc = msg_send(src_node->cluster->send_sock, clusterer_proto,
1319+
send_rc = msg_send(src_node->cluster->send_sock, src_node->proto,
13201320
&src_node->addr, 0, bin_buffer.s, bin_buffer.len, 0);
13211321

13221322
#ifndef CLUSTERER_EXTRA_BIN_DBG

modules/clusterer/topology.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int flood_message(bin_packet_t *packet, cluster_info_t *cluster,
2929
void handle_full_top_update(bin_packet_t *packet, node_info_t *source,
3030
int *ev_actions_required);
3131
void handle_internal_msg_unknown(bin_packet_t *received, cluster_info_t *cl,
32-
int packet_type, union sockaddr_union *src_su, int src_node_id);
32+
int packet_type, union sockaddr_union *src_su, int proto, int src_node_id);
3333
void handle_ls_update(bin_packet_t *received, node_info_t *src_node,
3434
int *ev_actions_required);
3535
void handle_unknown_id(node_info_t *src_node);

modules/proto_bin/bin_common.h

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
* Copyright (C) 2021 - OpenSIPS Foundation
3+
*
4+
* This file is part of opensips, a free SIP server.
5+
*
6+
* opensips is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2 of the License, or
9+
* (at your option) any later version
10+
*
11+
* opensips is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+
*
20+
*
21+
*/
22+
23+
static inline void bin_parse_headers(struct tcp_req *req){
24+
unsigned int *px;
25+
if(req->content_len == 0 && req->pos - req->buf < HEADER_SIZE){
26+
req->parsed = req->pos;
27+
return;
28+
}
29+
30+
if (!is_valid_bin_packet(req->buf)) {
31+
LM_ERR("Invalid packet marker, got %.4s\n", req->buf);
32+
req->error = TCP_REQ_BAD_LEN;
33+
return;
34+
}
35+
36+
px = (unsigned int*)(req->buf + MARKER_SIZE);
37+
req->content_len = (*px);
38+
if(req->pos - req->buf == req->content_len){
39+
LM_DBG("received a COMPLETE message\n");
40+
req->complete = 1;
41+
req->parsed = req->buf + req->content_len;
42+
} else if(req->pos - req->buf > req->content_len){
43+
LM_DBG("received MORE then a message\n");
44+
req->complete = 1;
45+
req->parsed = req->buf + req->content_len;
46+
} else {
47+
LM_DBG("received only PART of a message\n");
48+
req->parsed = req->pos;
49+
}
50+
}
51+
52+
static inline int bin_handle_req(struct tcp_req *req,
53+
struct tcp_connection *con, int _max_msg_chunks)
54+
{
55+
long size;
56+
57+
if (req->complete){
58+
/* update the timeout - we successfully read the request */
59+
tcp_conn_set_lifetime( con, tcp_con_lifetime);
60+
con->timeout = con->lifetime;
61+
62+
LM_DBG("completely received a message\n");
63+
/* rcv.bind_address should always be !=0 */
64+
/* just for debugging use sendipv4 as receiving socket FIXME*/
65+
con->rcv.proto_reserved1=con->id; /* copy the id */
66+
67+
/* prepare for next request */
68+
size=req->pos - req->parsed;
69+
70+
if (!size) {
71+
/* did not read any more things - we can release
72+
* the connection */
73+
LM_DBG("Nothing more to read on TCP conn %p, currently in state %d \n",
74+
con,con->state);
75+
if (req != &_bin_common_current_req) {
76+
/* we have the buffer in the connection tied buff -
77+
* detach it , release the conn and free it afterwards */
78+
con->con_req = NULL;
79+
}
80+
} else {
81+
LM_DBG("We still have things on the pipe - "
82+
"keeping connection \n");
83+
}
84+
85+
/* give the message to the registered functions */
86+
call_callbacks(req->buf, &con->rcv);
87+
88+
89+
if (!size && req != &_bin_common_current_req) {
90+
/* if we no longer need this tcp_req
91+
* we can free it now */
92+
pkg_free(req);
93+
}
94+
95+
con->msg_attempts = 0;
96+
97+
if (size) {
98+
memmove(req->buf, req->parsed, size);
99+
100+
init_tcp_req(req, size);
101+
102+
/* if we still have some unparsed bytes, try to parse them too*/
103+
return 1;
104+
}
105+
106+
} else {
107+
/* request not complete - check the if the thresholds are exceeded */
108+
if (con->msg_attempts==0)
109+
/* if first iteration, set a short timeout for reading
110+
* a whole SIP message */
111+
con->timeout = get_ticks() + tcp_max_msg_time;
112+
113+
con->msg_attempts ++;
114+
if (con->msg_attempts == _max_msg_chunks) {
115+
LM_ERR("Made %u read attempts but message is not complete yet - "
116+
"closing connection \n",con->msg_attempts);
117+
goto error;
118+
}
119+
120+
if (req == &_bin_common_current_req) {
121+
/* let's duplicate this - most likely another conn will come in */
122+
123+
LM_DBG("We didn't manage to read a full request\n");
124+
con->con_req = pkg_malloc(sizeof(struct tcp_req));
125+
if (con->con_req == NULL) {
126+
LM_ERR("No more mem for dynamic con request buffer\n");
127+
goto error;
128+
}
129+
130+
if (req->pos != req->buf) {
131+
/* we have read some bytes */
132+
memcpy(con->con_req->buf,req->buf,req->pos-req->buf);
133+
con->con_req->pos = con->con_req->buf + (req->pos-req->buf);
134+
} else {
135+
con->con_req->pos = con->con_req->buf;
136+
}
137+
138+
if (req->parsed != req->buf)
139+
con->con_req->parsed =con->con_req->buf+(req->parsed-req->buf);
140+
else
141+
con->con_req->parsed = con->con_req->buf;
142+
143+
con->con_req->complete=req->complete;
144+
con->con_req->content_len=req->content_len;
145+
con->con_req->error = req->error;
146+
}
147+
}
148+
149+
/* everything ok */
150+
return 0;
151+
error:
152+
/* report error */
153+
return -1;
154+
}

0 commit comments

Comments
 (0)