blob: 4c541cb3aac7fc6aa7aad8fa7188f8e4ead780c3 [file] [log] [blame]
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2
3/*
4 * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * (C) 2009-2012 by On-Waves
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
Philipp Maier87bd9be2017-08-22 16:35:41 +020023#pragma once
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020024
25#include <osmocom/core/msgb.h>
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +020026#include <osmocom/core/socket.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020027#include <osmocom/core/write_queue.h>
28#include <osmocom/core/timer.h>
29#include <osmocom/core/logging.h>
30
Neels Hofmeyr67793542017-09-08 04:25:16 +020031#include <osmocom/mgcp/mgcp_common.h>
Pau Espin Pedrol928a20b2022-09-23 15:38:24 +020032#include <osmocom/mgcp/osmux.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020033
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020034#include <arpa/inet.h>
35#include <sys/types.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
Eric55fdfc22021-08-13 00:14:18 +020038#include <pthread.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020039
Philipp Maierc66ab2c2020-06-02 20:55:34 +020040#include "mgcp_ratectr.h"
41
Philipp Maier87bd9be2017-08-22 16:35:41 +020042#define RTP_PORT_DEFAULT_RANGE_START 16002
43#define RTP_PORT_DEFAULT_RANGE_END RTP_PORT_DEFAULT_RANGE_START + 64
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020044
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020045/*
46 * Handling of MGCP Endpoints and the MGCP Config
47 */
48struct mgcp_endpoint;
49struct mgcp_config;
Philipp Maier14b27a82020-06-02 20:15:30 +020050struct mgcp_trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020051struct mgcp_rtp_end;
52
53#define MGCP_ENDP_CRCX 1
54#define MGCP_ENDP_DLCX 2
55#define MGCP_ENDP_MDCX 3
56
57/*
58 * what to do with the msg?
59 * - continue as usual?
60 * - reject and send a failure code?
61 * - defer? do not send anything
62 */
63#define MGCP_POLICY_CONT 4
64#define MGCP_POLICY_REJECT 5
65#define MGCP_POLICY_DEFER 6
66
Philipp Maier14b27a82020-06-02 20:15:30 +020067typedef int (*mgcp_reset)(struct mgcp_trunk *cfg);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020068typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone);
69
70/**
71 * Return:
72 * < 0 in case no audio was processed
73 * >= 0 in case audio was processed. The remaining payload
74 * length will be returned.
75 */
76typedef int (*mgcp_processing)(struct mgcp_endpoint *endp,
77 struct mgcp_rtp_end *dst_end,
78 char *data, int *len, int buf_size);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020079
Philipp Maier87bd9be2017-08-22 16:35:41 +020080struct mgcp_conn_rtp;
Philipp Maieracc10352018-07-19 18:07:57 +020081
82typedef int (*mgcp_processing_setup)(struct mgcp_endpoint *endp,
83 struct mgcp_conn_rtp *conn_dst,
84 struct mgcp_conn_rtp *conn_src);
85
Philipp Maier58128252019-03-06 11:28:18 +010086struct mgcp_rtp_codec;
87
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020088typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
Philipp Maier58128252019-03-06 11:28:18 +010089 const struct mgcp_rtp_codec **codec,
90 const char **fmtp_extra,
Philipp Maier87bd9be2017-08-22 16:35:41 +020091 struct mgcp_conn_rtp *conn);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020092
93/**
94 * This holds information on how to allocate ports
95 */
96struct mgcp_port_range {
Eric55fdfc22021-08-13 00:14:18 +020097 pthread_mutex_t lock;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098 /* addr or NULL to fall-back to default */
Eric2764bdb2021-08-23 22:11:47 +020099 char bind_addr_v4[INET6_ADDRSTRLEN];
100 char bind_addr_v6[INET6_ADDRSTRLEN];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200101
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200102 /* dynamically allocated */
103 int range_start;
104 int range_end;
105 int last_port;
Philipp Maier1cb1e382017-11-02 17:16:04 +0100106
107 /* set to true to enable automatic probing
108 * of the local bind IP-Address, bind_addr
109 * (or its fall back) is used when automatic
110 * probing fails */
111 bool bind_addr_probe;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200112};
113
Philipp Maiere726d4f2017-11-01 10:41:34 +0100114/* There are up to three modes in which the keep-alive dummy packet can be
Harald Welte1d1b98f2017-12-25 10:03:40 +0100115 * sent. The behaviour is controlled via the keepalive_interval member of the
Philipp Maiere726d4f2017-11-01 10:41:34 +0100116 * trunk config. If that member is set to 0 (MGCP_KEEPALIVE_NEVER) no dummy-
117 * packet is sent at all and the timer that sends regular dummy packets
118 * is no longer scheduled. If the keepalive_interval is set to -1, only
119 * one dummy packet is sent when an CRCX or an MDCX is performed. No timer
Harald Welte1d1b98f2017-12-25 10:03:40 +0100120 * is scheduled. For all vales greater 0, the timer is scheduled and the
Philipp Maiere726d4f2017-11-01 10:41:34 +0100121 * value is used as interval. See also mgcp_keepalive_timer_cb(),
122 * handle_modify_con(), and handle_create_con() */
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200123#define MGCP_KEEPALIVE_ONCE (-1)
Philipp Maiere726d4f2017-11-01 10:41:34 +0100124#define MGCP_KEEPALIVE_NEVER 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200125
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200126enum mgcp_role {
127 MGCP_BSC = 0,
128 MGCP_BSC_NAT,
129};
130
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200131struct mgcp_config {
132 int source_port;
Eric2764bdb2021-08-23 22:11:47 +0200133 char local_ip[INET6_ADDRSTRLEN];
134 char source_addr[INET6_ADDRSTRLEN];
135 char call_agent_addr[INET6_ADDRSTRLEN];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200136
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200137 /* RTP processing */
138 mgcp_processing rtp_processing_cb;
139 mgcp_processing_setup setup_rtp_processing_cb;
140
141 mgcp_get_format get_net_downlink_format_cb;
142
143 struct osmo_wqueue gw_fd;
144
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200145 struct mgcp_port_range net_ports;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200146 int endp_dscp;
Harald Welte55a92292021-04-28 19:06:34 +0200147 int endp_priority;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200148
Philipp Maier87bd9be2017-08-22 16:35:41 +0200149 int force_ptime;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200150
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200151 mgcp_reset reset_cb;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200152 mgcp_rqnt rqnt_cb;
153 void *data;
154
Philipp Maierd19de2e2020-06-03 13:55:33 +0200155 /* list holding the trunks */
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200156 struct llist_head trunks;
157
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158 enum mgcp_role role;
159
Pau Espin Pedrol928a20b2022-09-23 15:38:24 +0200160 /* Osmux usage policy: */
161 enum osmux_usage osmux_use;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200162 /* addr to bind the server to */
Eric2764bdb2021-08-23 22:11:47 +0200163 char osmux_addr[INET6_ADDRSTRLEN];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200164 /* The BSC-NAT may ask for enabling osmux on demand. This tells us if
165 * the osmux socket is already initialized.
166 */
Pau Espin Pedrolb7f52b42022-09-25 00:14:03 +0200167 bool osmux_initialized;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200168 /* osmux batch factor: from 1 to 4 maximum */
169 int osmux_batch;
170 /* osmux batch size (in bytes) */
171 int osmux_batch_size;
172 /* osmux port */
173 uint16_t osmux_port;
174 /* Pad circuit with dummy messages until we see the first voice
175 * message.
176 */
177 uint16_t osmux_dummy;
Philipp Maier12943ea2018-01-17 15:40:25 +0100178 /* domain name of the media gateway */
179 char domain[255+1];
Oliver Smithe36b7752019-01-22 16:31:36 +0100180
181 /* time after which inactive connections (CIs) get closed */
182 int conn_timeout;
Harald Welte9852e222020-03-08 10:22:14 +0100183
184 /* osmocom CTRL interface */
185 struct ctrl_handle *ctrl;
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200186
187 /* global rate counters to measure the MGWs overall performance and
188 * health */
189 struct mgcp_ratectr_global ratectr;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200190};
191
192/* config management */
193struct mgcp_config *mgcp_config_alloc(void);
194int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
195 enum mgcp_role role);
196int mgcp_vty_init(void);
Philipp Maier14b27a82020-06-02 20:15:30 +0200197void mgcp_trunk_set_keepalive(struct mgcp_trunk *trunk, int interval);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200198
199/*
200 * format helper functions
201 */
202struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
203
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200204
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200205int mgcp_send_reset_ep(struct mgcp_endpoint *endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200206int mgcp_send_reset_all(struct mgcp_config *cfg);
207
208
Harald Welte55a92292021-04-28 19:06:34 +0200209int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port, uint8_t dscp,
210 uint8_t prio);
Pau Espin Pedrol5ffd1272022-10-04 13:45:48 +0200211int mgcp_udp_send(int fd, const struct osmo_sockaddr *addr, const char *buf, int len);