comparison sip-in/invite_init.c @ 145:4b685a5d9bd4

sip-in code: split invite.c into 3 separate C modules
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 08 Oct 2022 19:31:05 -0800
parents sip-in/invite.c@c93c339271a7
children 257da5474e77
comparison
equal deleted inserted replaced
144:4e16aeafbfbf 145:4b685a5d9bd4
1 /*
2 * Here we implement our initial processing of SIP INVITE requests.
3 */
4
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <netinet/in.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <strings.h>
14 #include <syslog.h>
15 #include "../libsip/parse.h"
16 #include "../libsip/uas_basic.h"
17 #include "../libsip/grok_from.h"
18 #include "../libsip/req_supp.h"
19 #include "../libsip/sdp.h"
20 #include "../libsip/out_msg.h"
21 #include "call.h"
22
23 extern struct in_addr sip_bind_ip;
24 extern int cfg_use_100rel;
25 extern int cfg_force_pcma;
26 extern struct call *call_list;
27
28 extern struct call *find_call_by_sip_id();
29 extern char *get_single_header();
30
31 void
32 invite_new_call(req, ess, sin)
33 struct sip_pkt_rx *req;
34 struct uas_parse_hdrs *ess;
35 struct sockaddr_in *sin;
36 {
37 static unsigned cycle_tag_num, cycle_sdp_addend;
38 char uri_user[13], *called_nanp;
39 struct sip_msg_out resp;
40 struct grok_from gfrom;
41 struct supported_ext supp_ext;
42 char *hval, *unsup_ext;
43 int ext_100rel_req, ext_100rel_sup, use_100rel, use_pcma;
44 struct sdp_parse sdp_parse;
45 struct sdp_gen sdp_gen;
46 struct call *call;
47 char *dp, cdr_str[80];
48 unsigned cdr_num_len, cdr_cnam_len;
49 unsigned req_uri_len, to_hdr_len, copylen;
50 int rc;
51
52 /* extract called number from Request-URI */
53 rc = user_from_sip_uri(req->req_uri, uri_user, 12);
54 if (rc < 0) {
55 not_nanp: start_response_out_msg(&resp,
56 "416 Request-URI is not a NANP number");
57 error_resp: rc = add_resp_basic_headers(&resp, ess, req->req_method);
58 if (rc < 0) {
59 error_resp_toolong: syslog(LOG_ERR,
60 "INVITE early error response length exceeded");
61 return;
62 }
63 out_msg_finish(&resp);
64 sip_tx_packet(&resp, sin);
65 return;
66 }
67 if (uri_user[0] == '+') {
68 if (grok_number_string(uri_user+1, 0) != 11 ||
69 uri_user[1] != '1')
70 goto not_nanp;
71 called_nanp = uri_user + 2;
72 } else switch (grok_number_string(uri_user)) {
73 case 10:
74 called_nanp = uri_user;
75 break;
76 case 11:
77 if (uri_user[0] != '1')
78 goto not_nanp;
79 called_nanp = uri_user + 1;
80 break;
81 default:
82 goto not_nanp;
83 }
84 if (!is_nanp_valid_prefix(called_nanp))
85 goto not_nanp;
86 /* it is valid NANP - but is it one of ours? */
87 refresh_number_db();
88 if (!is_nanp_locally_owned(called_nanp)) {
89 start_response_out_msg(&resp,
90 "404 Called number does not belong here");
91 goto error_resp;
92 }
93 /* parse and validate From header */
94 rc = grok_from_header(ess->from, &gfrom);
95 if (rc < 0) {
96 start_response_out_msg(&resp, "400 Malformed From header");
97 goto error_resp;
98 }
99 /* validate To header for the purpose of tag addition */
100 req_uri_len = strlen(req->req_uri);
101 to_hdr_len = strlen(ess->to);
102 if (to_hdr_len == req_uri_len) {
103 if (strcasecmp(ess->to, req->req_uri)) {
104 bad_to_header: start_response_out_msg(&resp, "400 Bad To header");
105 goto error_resp;
106 }
107 } else if (to_hdr_len == req_uri_len + 2) {
108 if (ess->to[0] != '<')
109 goto bad_to_header;
110 if (strncasecmp(ess->to+1, req->req_uri, req_uri_len))
111 goto bad_to_header;
112 if (ess->to[req_uri_len+1] != '>')
113 goto bad_to_header;
114 } else
115 goto bad_to_header;
116 /* check 100rel and catch any unsupported requirements */
117 supp_ext.name = "100rel";
118 supp_ext.req_flag = &ext_100rel_req;
119 supp_ext.sup_flag = &ext_100rel_sup;
120 ext_100rel_req = ext_100rel_sup = 0;
121 rc = parse_require_supported(req, &supp_ext, 1, &unsup_ext);
122 if (rc < 0) {
123 start_response_out_msg(&resp, "420 Extension not supported");
124 rc = out_msg_add_header(&resp, "Unsupported", unsup_ext);
125 if (rc < 0)
126 goto error_resp_toolong;
127 goto error_resp;
128 }
129 if (ext_100rel_req)
130 use_100rel = 1;
131 else if (ext_100rel_sup)
132 use_100rel = cfg_use_100rel;
133 else
134 use_100rel = 0;
135 /* did the caller send an SDP message body? */
136 if (!req->msg_body_len) {
137 start_response_out_msg(&resp, "415 Missing SDP body");
138 error_415: rc = out_msg_add_header(&resp, "Accept", "application/sdp");
139 if (rc < 0)
140 goto error_resp_toolong;
141 goto error_resp;
142 }
143 hval = get_single_header(req, "Content-Type", "c", (int *) 0);
144 if (!hval) {
145 start_response_out_msg(&resp,
146 "415 Missing Content-Type header");
147 goto error_415;
148 }
149 if (strcasecmp(hval, "application/sdp")) {
150 start_response_out_msg(&resp, "415 Unsupported Content-Type");
151 goto error_415;
152 }
153 rc = parse_incoming_sdp(req->msg_body, req->msg_body_len, &sdp_parse);
154 if (rc < 0) {
155 start_response_out_msg(&resp, "488 Malformed SDP body");
156 goto error_resp;
157 }
158 switch (sdp_parse.codec_mask) {
159 case SDP_CODEC_MASK_PCMU:
160 use_pcma = 0;
161 break;
162 case SDP_CODEC_MASK_PCMA:
163 case SDP_CODEC_MASK_BOTH | SDP_CODEC_MASK_PCMA_PREF:
164 use_pcma = 1;
165 break;
166 case SDP_CODEC_MASK_BOTH:
167 use_pcma = cfg_force_pcma;
168 break;
169 default:
170 start_response_out_msg(&resp,
171 "488 Unsupported codec selection");
172 rc = add_resp_basic_headers(&resp, ess, req->req_method);
173 if (rc < 0)
174 goto error_resp_toolong;
175 rc = out_msg_add_header(&resp, "Content-Type",
176 "application/sdp");
177 if (rc < 0)
178 goto error_resp_toolong;
179 bzero(&sdp_gen, sizeof sdp_gen);
180 sdp_gen.owner_ip = sip_bind_ip;
181 sdp_gen.conn_ip = sip_bind_ip;
182 sdp_gen.codec_mask = SDP_CODEC_MASK_BOTH;
183 rc = out_msg_finish_sdp(&resp, &sdp_gen);
184 if (rc < 0)
185 goto error_resp_toolong;
186 sip_tx_packet(&resp, sin);
187 return;
188 }
189 /* SIP INVITE validation done - gather CDR info */
190 cdr_num_len = gfrom.user_len;
191 if (cdr_num_len > 33)
192 cdr_num_len = 33;
193 cdr_cnam_len = gfrom.cnam_len;
194 if (cdr_cnam_len > 33)
195 cdr_cnam_len = 33;
196 if (cdr_cnam_len)
197 sprintf(cdr_str, "%.*s (%s%.*s%s)", cdr_num_len, gfrom.user,
198 gfrom.cnam_quoted ? "\"" : "", cdr_cnam_len, gfrom.cnam,
199 gfrom.cnam_quoted ? "\"" : "");
200 else
201 sprintf(cdr_str, "%.*s", cdr_num_len, gfrom.user);
202 hval = get_single_header(req, "P-Asserted-Identity", (char *) 0,
203 (int *) 0);
204 /* check if GSM service is up */
205 rc = connect_gsm_mtcall();
206 if (rc < 0) {
207 gsm_offline: syslog(LOG_INFO, "Down-call from %s to %s", cdr_str, uri_user);
208 if (hval)
209 syslog(LOG_INFO, "Down-call PAI: %.100s", hval);
210 start_response_out_msg(&resp, "480 GSM service is offline");
211 goto error_resp;
212 }
213 rc = connect_tmgw_socket();
214 if (rc < 0)
215 goto gsm_offline;
216 /* stateful processing begins */
217 call = malloc(sizeof(struct call) + strlen(ess->call_id) +
218 strlen(ess->from) + req_uri_len + strlen(ess->via) + 19);
219 if (!call) {
220 syslog(LOG_CRIT, "failed malloc for incoming call!");
221 start_response_out_msg(&resp,
222 "503 Gateway resource allocation failure");
223 goto error_resp;
224 }
225 cycle_tag_num++;
226 if (cycle_tag_num >= 1000000)
227 cycle_tag_num = 0;
228 cycle_sdp_addend++;
229 if (cycle_sdp_addend >= 0x10000)
230 cycle_sdp_addend = 0;
231 bzero(call, sizeof(struct call));
232 dp = (char *)(call + 1);
233 copylen = strlen(ess->call_id) + 1;
234 call->sip_call_id = dp;
235 bcopy(ess->call_id, dp, copylen);
236 dp += copylen;
237 copylen = strlen(ess->from) + 1;
238 call->invite_from = dp;
239 bcopy(ess->from, dp, copylen);
240 dp += copylen;
241 call->invite_to = dp;
242 *dp++ = '<';
243 bcopy(req->req_uri, dp, req_uri_len);
244 dp += req_uri_len;
245 *dp++ = '>';
246 sprintf(dp, ";tag=in%06u", cycle_tag_num);
247 dp += 14;
248 copylen = strlen(ess->via) + 1;
249 call->invite_via = dp;
250 bcopy(ess->via, dp, copylen);
251 call->invite_cseq = ess->cseq_num;
252 bcopy(sin, &call->udp_sin, sizeof(struct sockaddr_in));
253 bcopy(called_nanp, call->called_nanp, 11);
254 call->from_uri = call->invite_from + (gfrom.uri - ess->from);
255 call->from_uri_len = gfrom.uri_len;
256 call->from_user = call->invite_from + (gfrom.user - ess->from);
257 call->from_user_len = gfrom.user_len;
258 call->use_100rel = use_100rel;
259 call->pstn_rtp_remote.sin_family = AF_INET;
260 call->pstn_rtp_remote.sin_addr = sdp_parse.ip_addr;
261 call->pstn_rtp_remote.sin_port = htons(sdp_parse.audio_port);
262 call->use_pcma = use_pcma;
263 call->in_tag_num = cycle_tag_num;
264 call->sdp_addend = cycle_sdp_addend;
265 /* generate 100 response */
266 start_response_out_msg(&resp, "100 Proceeding");
267 rc = fill_invite_resp_from_call(&resp, call);
268 if (rc < 0) {
269 syslog(LOG_ERR, "INVITE 100 response length exceeded");
270 free(call);
271 return;
272 }
273 out_msg_finish(&resp);
274 sip_tx_packet(&resp, sin);
275 /* add to call list */
276 call->next = call_list;
277 call_list = call;
278 syslog(LOG_INFO, "Call in%06u from %s to %s", call->in_tag_num,
279 cdr_str, uri_user);
280 if (hval)
281 syslog(LOG_INFO, "Call in%06u PAI: %.100s", call->in_tag_num,
282 hval);
283 /* send CRCX to TMGW */
284 tmgw_send_crcx(call);
285 call->overall_state = OVERALL_STATE_CRCX;
286 call->sip_state = SIP_STATE_INVITE_PROC;
287 }
288
289 void
290 handle_sip_invite(req, ess, sin)
291 struct sip_pkt_rx *req;
292 struct uas_parse_hdrs *ess;
293 struct sockaddr_in *sin;
294 {
295 struct call *call;
296
297 call = find_call_by_sip_id(ess->call_id);
298 if (call)
299 invite_existing_call(req, ess, sin, call);
300 else
301 invite_new_call(req, ess, sin);
302 }