view sip-in/sip_udp.c @ 82:ff4b76a107a1

sip-in: process responses as UAC for BYE
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 20 Sep 2022 20:33:09 -0800
parents 15c9e1f8f756
children
line wrap: on
line source

/*
 * In this module we implement our UDP socket for SIP,
 * and the associated lowest-level protocol handling.
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <syslog.h>
#include <unistd.h>
#include "../libsip/parse.h"
#include "../libsip/out_msg.h"

extern struct in_addr sip_bind_ip;
extern unsigned sip_bind_port;

int sip_socket;

open_sip_udp_socket()
{
	struct sockaddr_in sin;
	int rc;

	sip_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (sip_socket < 0) {
		syslog(LOG_CRIT, "socket(AF_INET, SOCK_DGRAM, 0): %m");
		return(-1);
	}
	sin.sin_family = AF_INET;
	sin.sin_addr = sip_bind_ip;
	sin.sin_port = htons(sip_bind_port);
	rc = bind(sip_socket, (struct sockaddr *) &sin, sizeof sin);
	if (rc < 0) {
		syslog(LOG_CRIT, "bind of SIP UDP socket: %m");
		return(-1);
	}
	update_max_fd(sip_socket);
	return(0);
}

void
sip_socket_select()
{
	struct sip_pkt_rx pkt;
	struct sockaddr_in sin;
	socklen_t addrlen;
	int rc;

	addrlen = sizeof sin;
	rc = recvfrom(sip_socket, pkt.pkt_buffer, MAX_SIP_RX_PACKET, 0,
			(struct sockaddr *) &sin, &addrlen);
	if (rc <= 0)
		return;
	pkt.pkt_length = rc;
	log_sip_msg_rx(pkt.pkt_buffer, pkt.pkt_length, &sin);
	rc = parse_incoming_sip_msg(&pkt);
	if (rc < 0) {
		/* parse errors */
		if (rc == -2 && pkt.parse_msgtype == SIP_MSG_TYPE_REQ)
			syslog(LOG_ERR,
				"SIP %.16s msg exceeds MAX_HEADER_FIELDS",
				pkt.req_method);
		else if (rc == -2 && pkt.parse_msgtype == SIP_MSG_TYPE_RESP)
			syslog(LOG_ERR,
				"SIP response msg exceeds MAX_HEADER_FIELDS");
		/* in any case, silently discard */
		return;
	}
	/* dispatch good-so-far SIP message */
	if (pkt.parse_msgtype == SIP_MSG_TYPE_REQ)
		process_sip_request(&pkt, &sin);
	else if (pkt.parse_msgtype == SIP_MSG_TYPE_RESP)
		process_sip_response(&pkt, &sin);
}

void
sip_tx_packet(msg, sin)
	struct sip_msg_out *msg;
	struct sockaddr_in *sin;
{
	socklen_t addrlen;

	addrlen = sizeof(struct sockaddr_in);
	sendto(sip_socket, msg->buf, msg->msg_len, 0, (struct sockaddr *) sin,
		addrlen);
	log_sip_msg_tx(msg->buf, msg->msg_len, sin);
}