/src/opensips/net/trans_trace.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2017 OpenSIPS Solutions |
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 | | #include "../trace_api.h" |
21 | | #include "trans_trace.h" |
22 | | |
23 | | str trans_trace_str_status[] = { |
24 | | str_init("SUCCESS"), |
25 | | str_init("FAILURE") |
26 | | }; |
27 | | |
28 | | str trans_trace_str_event[] = { |
29 | | str_init("ACCEPTED"), |
30 | | str_init("CONNECT_START"), |
31 | | str_init("CONNECTED"), |
32 | | str_init("CLOSED"), |
33 | | str_init("STATS") |
34 | | }; |
35 | | |
36 | | static str TCP_PROTO_ID = str_init("TCP"); |
37 | | static str TLS_PROTO_ID = str_init("TLS"); |
38 | | static str WS_PROTO_ID = str_init("WS"); |
39 | | static str WSS_PROTO_ID = str_init("WSS"); |
40 | | static str BINS_PROTO_ID = str_init("BINS"); |
41 | | |
42 | | /* error reasons */ |
43 | | str AS_CONNECT_INIT = str_init("Async connect in progress..."); |
44 | | str CONNECT_OK = str_init("Successfully connected..."); |
45 | | str ASYNC_CONNECT_OK = str_init("Successfully connected asynchronously..."); |
46 | | str ACCEPT_OK = str_init("Connection accepted..."); |
47 | | str ACCEPT_FAIL = str_init("Failed to accept connection..."); |
48 | | str CONNECT_FAIL = str_init("Failed to connect..."); |
49 | | |
50 | | |
51 | | |
52 | | static void add_proto( trace_message message, int proto); |
53 | | |
54 | | int net_trace_proto_id=-1; |
55 | | trace_proto_t* net_trace_api=0; |
56 | | |
57 | | trace_message create_trace_message( unsigned long long id, union sockaddr_union* src, |
58 | | union sockaddr_union* dst, int proto, void* dest) |
59 | 0 | { |
60 | 0 | int net_proto; |
61 | 0 | static int correlation_id = -1, correlation_vendor = -1; |
62 | |
|
63 | 0 | str str_id; |
64 | |
|
65 | 0 | if ( !net_trace_api ) { |
66 | 0 | LM_BUG("trace api not loaded! should have been loaded!\n"); |
67 | 0 | return 0; |
68 | 0 | } |
69 | | |
70 | 0 | trace_message message; |
71 | 0 | switch ( proto ) { |
72 | 0 | case PROTO_TCP: |
73 | 0 | net_proto = IPPROTO_TCP; |
74 | 0 | break; |
75 | 0 | case PROTO_TLS: |
76 | 0 | net_proto = IPPROTO_IDP; |
77 | 0 | break; |
78 | 0 | case PROTO_WS: |
79 | 0 | net_proto = IPPROTO_ESP; |
80 | 0 | break; |
81 | 0 | case PROTO_WSS: |
82 | 0 | net_proto = IPPROTO_ESP; |
83 | 0 | break; |
84 | 0 | case PROTO_BINS: |
85 | 0 | net_proto = IPPROTO_IDP; |
86 | 0 | break; |
87 | 0 | default: |
88 | 0 | return 0; |
89 | 0 | } |
90 | | |
91 | 0 | message = net_trace_api->create_trace_message( src, dst, |
92 | 0 | net_proto, 0, net_trace_proto_id, dest); |
93 | |
|
94 | 0 | str_id.s = int2str( id, &str_id.len ); |
95 | 0 | if ( correlation_vendor == -1 || correlation_id == - 1) { |
96 | 0 | if ( net_trace_api->get_data_id("correlation_id", &correlation_vendor, &correlation_id ) < 0 ) { |
97 | 0 | LM_ERR("can't find correlation id chunk!\n"); |
98 | 0 | return 0; |
99 | 0 | } |
100 | 0 | } |
101 | | |
102 | 0 | if ( net_trace_api->add_chunk( message, str_id.s, str_id.len, TRACE_TYPE_STR, |
103 | 0 | correlation_id, correlation_vendor) < 0) { |
104 | 0 | LM_ERR("failed to add correlation id! aborting trace...!\n"); |
105 | 0 | return 0; |
106 | 0 | } |
107 | 0 | add_proto( message, proto); |
108 | |
|
109 | 0 | return message; |
110 | 0 | } |
111 | | |
112 | | |
113 | | void add_trace_data( void* message, char* key, str* value) |
114 | 0 | { |
115 | 0 | if ( !message || !key || !value || !value->len || !value->s ) { |
116 | 0 | LM_ERR("invalid input data!\n"); |
117 | 0 | return; |
118 | 0 | } |
119 | | |
120 | 0 | net_trace_api->add_payload_part( message, key, value); |
121 | |
|
122 | 0 | return; |
123 | 0 | } |
124 | | |
125 | | int send_trace_message( void* message, void* destination) |
126 | 0 | { |
127 | 0 | if ( net_trace_api->send_message( message, destination, 0) < 0 ) { |
128 | 0 | LM_ERR("failed to trace message!\n"); |
129 | 0 | net_trace_api->free_message( message ); |
130 | 0 | return -1; |
131 | 0 | } |
132 | | |
133 | 0 | net_trace_api->free_message( message ); |
134 | |
|
135 | 0 | return 0; |
136 | 0 | } |
137 | | |
138 | | static void add_proto( trace_message message, int proto) |
139 | 0 | { |
140 | 0 | switch ( proto ) { |
141 | 0 | case PROTO_TCP: |
142 | 0 | add_trace_data( message, "Protocol", &TCP_PROTO_ID ); |
143 | 0 | break; |
144 | 0 | case PROTO_TLS: |
145 | 0 | add_trace_data( message, "Protocol", &TLS_PROTO_ID ); |
146 | 0 | break; |
147 | 0 | case PROTO_WS: |
148 | 0 | add_trace_data( message, "Protocol", &WS_PROTO_ID ); |
149 | 0 | break; |
150 | 0 | case PROTO_WSS: |
151 | 0 | add_trace_data( message, "Protocol", &WSS_PROTO_ID ); |
152 | 0 | break; |
153 | 0 | case PROTO_BINS: |
154 | 0 | add_trace_data( message, "Protocol", &BINS_PROTO_ID ); |
155 | 0 | break; |
156 | 0 | default: |
157 | 0 | break; |
158 | 0 | } |
159 | 0 | } |
160 | | |
161 | | int trace_message_atonce( int proto, unsigned long long id, union sockaddr_union* src, |
162 | | union sockaddr_union* dst,trans_trace_event event, |
163 | | trans_trace_status status, str* data, void* destination) |
164 | 0 | { |
165 | 0 | trace_message message; |
166 | |
|
167 | 0 | message = create_trace_message( id, src, dst, proto, destination); |
168 | 0 | if ( !message ) { |
169 | 0 | LM_ERR("failed to create the message!\n"); |
170 | 0 | return -1; |
171 | 0 | } |
172 | | |
173 | 0 | add_trace_data( message, "Event", &trans_trace_str_event[event]); |
174 | 0 | add_trace_data( message, "Status", &trans_trace_str_status[status]); |
175 | |
|
176 | 0 | if ( data && data->s && data->len) { |
177 | 0 | add_trace_data( message, "Message", data); |
178 | 0 | } |
179 | | |
180 | |
|
181 | 0 | if ( send_trace_message( message, destination) < 0 ) { |
182 | 0 | LM_ERR("failed to send message!\n"); |
183 | 0 | return -1; |
184 | 0 | } |
185 | | |
186 | | |
187 | 0 | return 0; |
188 | 0 | } |
189 | | |
190 | | |
191 | | int tcpconn2su( struct tcp_connection* c, union sockaddr_union* src_su, |
192 | | union sockaddr_union* dst_su) |
193 | 0 | { |
194 | |
|
195 | 0 | if ( !c || !src_su || !dst_su ) { |
196 | 0 | LM_ERR("bad input!\n"); |
197 | 0 | return -1; |
198 | 0 | } |
199 | | |
200 | 0 | if ( init_su( src_su, &c->rcv.src_ip, c->rcv.src_port) < 0 ) { |
201 | 0 | LM_ERR("failed to create source su!\n"); |
202 | 0 | return -1; |
203 | 0 | } |
204 | | |
205 | 0 | if ( init_su( dst_su, &c->rcv.dst_ip, c->rcv.dst_port) < 0 ) { |
206 | 0 | LM_ERR("failed to create destination su!\n"); |
207 | 0 | return -1; |
208 | 0 | } |
209 | | |
210 | 0 | return 0; |
211 | 0 | } |
212 | | |
213 | | |
214 | | int check_trace_route( struct script_route_ref* rt_ref, |
215 | | struct tcp_connection* conn) |
216 | 0 | { |
217 | 0 | struct sip_msg *req; |
218 | | |
219 | | /* route not set */ |
220 | 0 | if ( !ref_script_route_is_valid(rt_ref) ) |
221 | 0 | return 1; |
222 | | |
223 | 0 | req = get_dummy_sip_msg(); |
224 | 0 | if(req == NULL) { |
225 | 0 | LM_ERR("No more memory\n"); |
226 | 0 | return -1; |
227 | 0 | } |
228 | | |
229 | | /* set request route type */ |
230 | 0 | set_route_type( REQUEST_ROUTE ); |
231 | |
|
232 | 0 | memcpy( &req->rcv, &conn->rcv, sizeof( struct receive_info )); |
233 | | |
234 | | /* run given hep route */ |
235 | 0 | if (run_top_route(sroutes->request[rt_ref->idx], req) & ACT_FL_DROP){ |
236 | 0 | conn->flags |= F_CONN_TRACE_DROPPED; |
237 | 0 | release_dummy_sip_msg(req); |
238 | 0 | return 0; |
239 | 0 | } |
240 | | |
241 | 0 | release_dummy_sip_msg(req); |
242 | 0 | return 1; |
243 | 0 | } |