Coverage Report

Created: 2025-07-11 06:28

/src/opensips/net/trans.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2015 OpenSIPS Project
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
 * history:
22
 * ---------
23
 *  2015-01-xx  created (razvanc)
24
 */
25
26
#include <string.h>
27
#include "trans.h"
28
#include "api_proto.h"
29
#include "../mem/mem.h"
30
#include "../sr_module.h"
31
#include "../socket_info.h"
32
#include "proto_tcp/proto_tcp_handler.h"
33
#include "proto_udp/proto_udp_handler.h"
34
35
36
/*
37
 * we need to always populate this structure at startup, at least the SIP
38
 * protocols, because we never know what kind of traffic we receive and have
39
 * to print its name
40
 */
41
struct proto_info protos[PROTO_LAST - PROTO_NONE + 1] = {
42
  { .name = NULL,  .default_rfc_port = 0 }, /* PROTO_NONE */
43
44
  { .name = "udp",  .default_rfc_port = 5060 }, /* PROTO_UDP */
45
  { .name = "tcp",  .default_rfc_port = 5060 }, /* PROTO_TCP */
46
  { .name = "tls",  .default_rfc_port = 5061 }, /* PROTO_TLS */
47
  { .name = "sctp", .default_rfc_port = 5060 }, /* PROTO_SCTP */
48
  { .name = "ws",   .default_rfc_port = 80 },   /* PROTO_WS */
49
  { .name = "wss",  .default_rfc_port = 443 },  /* PROTO_WSS */
50
  { .name = "ipsec",.default_rfc_port = 5062 }, /* PROTO_IPSEC */
51
52
  { .name = "bin",  .default_port = 5555 },     /* PROTO_BIN */
53
  { .name = "bins", .default_port = 5556 },     /* PROTO_BINS */
54
  /* populate here for other protos - not necessary right now */
55
};
56
57
static struct socket_id *cmd_listeners;
58
59
0
#define PROTO_PREFIX_LEN (sizeof(PROTO_PREFIX) - 1)
60
61
int trans_load(void)
62
0
{
63
0
  int id;
64
0
  struct sr_module *mod;
65
0
  const cmd_export_t *cmd;
66
0
  int found_all = 0;
67
0
  int found_proto;
68
0
  api_proto_init abind;
69
0
  struct proto_info pi;
70
71
  /* go through all protocol modules loaded and load only the ones
72
   * that are prefixed with the PROTO_PREFIX token */
73
0
  for (mod = modules; mod; mod = mod->next) {
74
0
    if (strncmp(PROTO_PREFIX, mod->exports->name, PROTO_PREFIX_LEN) != 0)
75
0
      continue;
76
0
    found_proto = 0;
77
    /* we have a transport module here - check for protocols */
78
0
    for (cmd = mod->exports->cmds; cmd && cmd->name; cmd++) {
79
0
      if (strcmp("proto_init", cmd->name)!=0)
80
0
        continue;
81
0
      abind = (api_proto_init)cmd->function;
82
0
      memset(&pi, 0, sizeof(pi));
83
0
      if (abind(&pi) < 0) {
84
0
        LM_ERR("cannot load protocol's functions for %s\n",
85
0
            cmd->name);
86
0
        return -1;
87
0
      }
88
      /* double check if it is a known/valid proto */
89
0
      if (pi.id < PROTO_FIRST || pi.id >= PROTO_OTHER) {
90
0
        LM_ERR("Unknown protocol id %d; check sip_protos structure!\n", pi.id);
91
0
        return -1;
92
0
      }
93
      /* double check the name of the proto */
94
0
      if (parse_proto((unsigned char *)pi.name, strlen(pi.name), &id) < 0) {
95
0
        LM_ERR("Cannot parse protocol %s\n", pi.name);
96
0
        return -1;
97
0
      }
98
0
      if (id != pi.id) {
99
0
        LM_ERR("Protocol ID mismatch %d != %d\n", id, pi.id);
100
0
        return -1;
101
0
      }
102
0
      found_proto = 1;
103
      /* check if there is any listener for this protocol */
104
0
      if (!proto_has_listeners(pi.id)) {
105
0
        LM_DBG("No listener defined for proto %s\n", pi.name);
106
0
        continue;
107
0
      }
108
109
      /* check if already added */
110
0
      if (protos[id].id != PROTO_NONE) {
111
0
        LM_ERR("Protocol already loaded %s\n", pi.name);
112
0
        return -1;
113
0
      }
114
      /* all good now */
115
0
      found_all++;
116
      /* copy necessary info */
117
0
      protos[pi.id].id = pi.id;
118
0
      protos[pi.id].name = pi.name;
119
0
      protos[pi.id].default_port = pi.default_port;
120
0
      protos[pi.id].tran = pi.tran;
121
0
      protos[pi.id].net = pi.net;
122
0
    }
123
0
    if (found_proto)
124
0
      continue;
125
0
    LM_ERR("No binding found for protocol %s\n", mod->exports->name);
126
0
    return -1;
127
0
  }
128
  /* return whether we found any protocol or not */
129
0
  return found_all;
130
0
}
131
#undef PROTO_PREFIX_LEN
132
133
134
int add_listening_socket(struct socket_id *sock)
135
0
{
136
  /*
137
   * XXX: using the new version, the protocol _MUST_ be specified
138
   * otherwise UDP will be assumed
139
   */
140
0
  enum sip_protos proto = sock->proto;
141
142
  /* validate the protocol */
143
0
  if (proto < PROTO_FIRST || proto >= PROTO_LAST) {
144
0
    LM_BUG("invalid protocol number %d\n", proto);
145
0
    return -1;
146
0
  }
147
148
  /* convert to socket_info */
149
0
  if (new_sock2list(sock, &protos[proto].listeners) < 0) {
150
0
    LM_ERR("cannot add socket to the list\n");
151
0
    return -1;
152
0
  }
153
154
0
  return 0;
155
0
}
156
157
int add_cmd_listening_socket(char *name, int port, int proto)
158
0
{
159
0
  struct socket_id *tmp = pkg_malloc(sizeof(struct socket_id));
160
0
  if (!tmp) {
161
0
    fprintf(stderr, "no more pkg memory\n");
162
0
    return -1;
163
0
  }
164
0
  memset(tmp, 0, sizeof(struct socket_id));
165
0
  tmp->name = name;
166
0
  tmp->port = port;
167
0
  tmp->proto = proto;
168
0
  tmp->next = cmd_listeners;
169
0
  cmd_listeners = tmp;
170
171
0
  return 0;
172
0
}
173
174
175
int fix_cmd_listening_sockets(void)
176
0
{
177
0
  struct socket_id *si, *prev;
178
0
  for (si = cmd_listeners; si;) {
179
0
    if (si->proto == PROTO_NONE)
180
0
      si->proto = PROTO_UDP;
181
0
    if (add_listening_socket(si) < 0)
182
0
      LM_ERR("Cannot add socket <%s>, skipping...\n", si->name);
183
0
    prev = si;
184
0
    si = si->next;
185
0
    pkg_free(prev);
186
0
  }
187
0
  return 0;
188
0
}
189
190
191
/*
192
 * return 0 on success, -1 on error */
193
int fix_all_socket_lists(void)
194
0
{
195
0
  int i;
196
0
  int found = 0;
197
0
  static char buf[PROTO_NAME_MAX_SIZE /* currently we shouldn't hardcode that much */];
198
0
  char *p;
199
200
0
  for (i = PROTO_FIRST; i < PROTO_LAST; i++) {
201
0
    if (protos[i].id != PROTO_NONE) {
202
0
      if (fix_socket_list(&protos[i].listeners)!=0) {
203
0
        LM_ERR("fix_socket_list for %d failed\n", protos[i].id);
204
0
        goto error;
205
0
      }
206
207
0
      found++;
208
0
    } else if (proto_has_listeners(i)) {
209
0
      p = proto2str(i, buf);
210
0
      if (p == NULL)
211
0
        goto error;
212
0
      *p = '\0';
213
214
0
      LM_ERR("listeners found for protocol %s, but no module "
215
0
          "can handle it, %d, %d \n", buf,i,protos[i].id);
216
0
      goto error;
217
0
    }
218
0
  }
219
220
0
  if (!found && !testing_framework) {
221
0
    LM_ERR("no listening sockets\n");
222
0
    goto error;
223
0
  }
224
225
0
  return 0;
226
0
error:
227
0
  return -1;
228
0
}
229
230
231
int trans_init_udp_listeners(void)
232
0
{
233
0
  struct socket_info_full *sif;
234
0
  int i;
235
236
0
  for (i = PROTO_FIRST; i < PROTO_LAST; i++)
237
0
    if (protos[i].id != PROTO_NONE)
238
0
      for( sif=protos[i].listeners ; sif ; sif=sif->next ) {
239
0
        struct socket_info *si = &sif->socket_info;
240
0
        if (is_udp_based_proto(si->proto)) {
241
0
          if (protos[i].tran.init_listener(si)<0) {
242
0
            LM_ERR("failed to init listener [%.*s], proto %s\n",
243
0
              si->name.len, si->name.s,
244
0
              protos[i].name );
245
0
            return -1;
246
0
          }
247
0
          if (protos[i].tran.bind_listener && protos[i].tran.bind_listener(si)<0) {
248
0
            LM_ERR("failed to bind listener [%.*s], proto %s\n",
249
0
              si->name.len, si->name.s,
250
0
              protos[i].name );
251
0
            return -1;
252
0
          }
253
0
        }
254
        /* set first IPv4 and IPv6 listeners for this proto */
255
0
        update_default_socket_info(si);
256
0
      }
257
258
0
  return 0;
259
0
}
260
261
void print_all_socket_lists(void)
262
0
{
263
0
  struct socket_info_full *sif;
264
0
  int i;
265
266
267
0
  for (i = PROTO_FIRST; i < PROTO_LAST; i++) {
268
0
    if (protos[i].id == PROTO_NONE)
269
0
      continue;
270
271
0
    for ( sif = protos[i].listeners; sif; sif = sif->next ) {
272
0
      const struct socket_info *si = &sif->socket_info;
273
0
      if (si->flags & SI_INTERNAL)
274
0
        continue;
275
0
      printf("             %s: %s [%s]:%s%s%s%s\n", protos[i].name,
276
0
          si->name.s, si->address_str.s, si->port_no_str.s,
277
0
          si->flags & SI_IS_MCAST ? " mcast" : "",
278
0
          si->flags & SI_FRAG ? " allow_fragments" : "",
279
0
          is_anycast(si)? " anycast" : "");
280
0
    }
281
0
  }
282
0
}