Coverage Report

Created: 2025-07-09 06:29

/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
}