⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nsrsbc.c

📁 简单的基于SIP的会话边界控制器
💻 C
字号:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <osipparser2/osip_parser.h>
#include <osipparser2/osip_message.h>

#include "nsrsbc.h"
#include "sessctl.h"
#include "regctl.h"
#include "cmdline.h"

struct gengetopt_args_info args_info;	/* gengeopt declarations */
static  int exit_program=0;		/* module local data */
int interface_sock = 0;
char interface_buffer[BUFFER_SIZE];

/*
 * local prototypes
 */
static void sighandler(int sig);

int main (int argc, char *argv[]) 
{
	int sts;
	int access;
	char buff [BUFFER_SIZE];
	size_t buflen;
	sip_ticket_t ticket;
	struct in_addr addr;
	struct sigaction act;

	/* parser user parameter */
	if (cmdline_parser (argc, argv, &args_info) != 0)
	{
		cmdline_parser_free(&args_info);
		exit(1);
	}
	if (cmdline_parser_configfile (args_info.conf_filepath_arg, &args_info, 1, 0, 1) != 0)
	{
		cmdline_parser_free(&args_info);
		exit(1);
	}
	printf ("sbc inbound ip address: %s\n", args_info.inaddr_arg);
	printf ("sbc outbound ip address: %s\n", args_info.outaddr_arg);
	printf ("sip proxy ip address: %s\n", args_info.proxy_addr_arg);
	printf ("rtp_port_low: %d\n", args_info.rtp_port_low_arg);
	printf ("rtp_port_high: %d\n", args_info.rtp_port_high_arg);
	printf ("rtp_timeout: %d\n", args_info.rtp_timeout_arg);
	printf ("hosts_deny_sip: %s\n", args_info.hosts_deny_sip_arg);
	printf ("hosts_allow_sip: %s\n", args_info.hosts_allow_sip_arg);
	printf ("nat function: %d\n", args_info.nat_flag);
	printf ("security function: %d\n", args_info.security_flag);
	printf ("bandwidth control function: %d\n", args_info.bandctrl_flag);
	printf ("protocol interworking function: %d\n", args_info.interworking_flag);
	
       /* initialize Session and Register Information Table */
       memset(sip_sess_ctl,0,sizeof(sip_sess_ctl));
       memset(sip_reg_ctl,0,sizeof(sip_reg_ctl));

      /*
 	* setup signal handlers
 	*/
   	act.sa_handler=sighandler;
   	sigemptyset(&act.sa_mask);
   	act.sa_flags=SA_RESTART;
   	if (sigaction(SIGTERM, &act, NULL)) {
      		printf("Failed to install SIGTERM handler");
   	}
   	if (sigaction(SIGINT, &act, NULL)) {
      		printf("Failed to install SIGINT handler");
   	}

	/* initialize the RTP proxy */
	sts = rtpproxy_init();
	if (sts != STS_SUCCESS) {
		printf("ERROR:main(): unable to initialize RTPProxy - aborting!\n"); 
		exit(1);
	}
	
	/* init the oSIP parser */
	parser_init();

	/* init interface socket */
	memset(&addr,0,sizeof(addr));
	if (inet_aton(args_info.inaddr_arg, &addr) < 0) {
		printf("interface_sock: proxy ip error!\n");
	}
	interface_sock = sockbind(addr,INTERFACE_SENDING_PORT);
	if (interface_sock == 0) return STS_FAILURE;
	
	/* listen for incoming messages */
	sts = sipsock_listen();
	if (sts == STS_FAILURE) {
		printf("ERROR:main(): unable to bind to SIP listening socket - aborting!\n"); 
		exit(1);
	}

	/* initialize the registration facility */
   	//register_init();
	
	/*****************************
	 * Main loop
	 *****************************/
	while (!exit_program) {
		while (sipsock_wait() <= 0) {
			/* got no input, here by timeout. do aging */
			register_agemap();
			if (exit_program) goto exit_prg;
         	}
		
		/*
	 	 * got input, process sip message
	 	 */
	 	ticket.direction = 0;
		//ticket.protocol = PROTO_UDP;
		buflen = sipsock_read(&buff, sizeof(buff)-1, &ticket.from, &ticket.protocol);
		buff[buflen]='\0';
		printf("main(): Recevice Packet from %s:%d\n", inet_ntoa(ticket.from.sin_addr), ntohs(ticket.from.sin_port));
		
		/* Access Control */
		access = accesslist_check(ticket.from);
		if (access == 0) {
			printf("Access for this packet was denied\n");
			continue;
		}
		else
			printf("Access for this packet was accepted\n");

		/* Integrity checks and Repair */
		//sts = sip_integrity_check(buff, buflen);
		//if (sts != STS_SUCCESS) {
		//	printf("Integrity check failed!\n");
		//	continue;
		//}
		
		sts = osip_message_init(&ticket.sipmsg);
		ticket.sipmsg->message = NULL;
		if (sts != 0) {
			printf("ERROR: osip_message_init() failed...\n");
			continue;
		}
		
		/*
		 * RFC 3261, Section 16.3 step 1
		 * Proxy Behavior - Request Validation - Reasonable Syntax
		 * (parse the received message)
		 */
		sts = osip_message_parse(ticket.sipmsg, buff, buflen);
		if (sts != 0) {
			printf("ERROR: osip_message_parse() failed... \n");
			/* skip and free resources */
			goto end_loop; 
		}

	
		printf("%s\n",buff);


		memset(interface_buffer,0,sizeof(interface_buffer));

              /* Get username information */
		osip_from_t *from;
		from = osip_message_get_from(ticket.sipmsg);
		char *username;
		username = osip_uri_get_username(osip_from_get_url(from));

		sprintf(interface_buffer,"<usrname>%s</usrname><srcsip>%s</srcsip>",username,buff);

		/*
		 * RFC 3261, Section 16.3 step 2
		 * Proxy Behavior - Request Validation - URI scheme
		 * (check request URI and refuse with 416 if not understood)
		 */
		/* NOT IMPLEMENTED */

		/*
		 * RFC 3261, Section 16.3 step 3
		 * Proxy Behavior - Request Validation - Max-Forwards check
		 * (check Max-Forwards header and refuse with 483 if too many hops)
		 */
		{
			osip_header_t *max_forwards;
			int forwards_count = DEFAULT_MAXFWD;

			osip_message_get_max_forwards(ticket.sipmsg, 0, &max_forwards);
			if (max_forwards && max_forwards->hvalue) {
				forwards_count = atoi(max_forwards->hvalue);
			}

			if (forwards_count <= 0) {
				//sip_gen_response(&ticket, 483 /*Too many hops*/);
				goto end_loop;
			}
		}
		
		/*
		 * RFC 3261, Section 16.3 step 4
		 * Proxy Behavior - Request Validation - Loop Detection check
		 * (check for loop and return 482 if a loop is detected)
		 */
		 /* NOT IMPLEMENTED */
		 
		/*
		 * RFC 3261, Section 16.3 step 5
		 * Proxy Behavior - Request Validation - Proxy-Require check
		 * (check Proxy-Require header and return 420 if unsupported option)
		 */
		/* NOT IMPLEMENTED */

		/*
		 * RFC 3261, Section 16.5
		 * Proxy Behavior - Determining Request Targets
		 */
		/* NOT IMPLEMENTED */
		
		/*********************************
		* The message did pass all the
		* tests above and is now ready
		* to be edited.
		*********************************/
		if (MSG_IS_REQUEST(ticket.sipmsg)) {
		       if (MSG_IS_REGISTER(ticket.sipmsg)){
				sts = proxy_rewrite_register(&ticket);
				if(!sts)
					printf("rewite register request successful!\n");
		       }
		       else{
				sts = proxy_request(&ticket);
				if(!sts)
		              	printf("rewite other request successful!\n");
		       }
		}
		else if (MSG_IS_RESPONSE(ticket.sipmsg)) {
		       if (MSG_IS_RESPONSE_FOR(ticket.sipmsg,"REGISTER")) {
		       	sts = proxy_rewrite_register_response(&ticket);
		       	if(!sts)
		       		printf("rewite register response successful!\n");
		       }
		       else{
				sts = proxy_response(&ticket);
				if(!sts)
		              	printf("rewite other response successful!\n");
		       }
		} else {
			printf("ERROR: received unsupported SIP type %s %s",
			    (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES", ticket.sipmsg->sip_method);
		}

   //        printf("%s\n",interface_buffer);
   		/* send info to interface */
		struct sockaddr_in destaddr;
		if (interface_sock == 0) {
			printf("interface_sock: interface send socket not allocated!\n");
			return STS_FAILURE;
		}
		destaddr.sin_family = AF_INET;
		memcpy(&destaddr.sin_addr.s_addr, &addr, sizeof(struct in_addr));
		destaddr.sin_port= htons(INTERFACE_LISTENING_PORT);
		sts = sendto(interface_sock, interface_buffer, sizeof(interface_buffer), 0, (const struct sockaddr *)&destaddr, (socklen_t)sizeof(destaddr));
	       if (sts == -1) {
         		return STS_FAILURE;
      		}
      		
		/*********************************
		* Done with proxying. Message
		* has been sent to its destination.
		*********************************/
		
		/* free the SIP message buffers */
		end_loop:
			osip_message_free(ticket.sipmsg);
	}
	
exit_prg:
	/* END */
	printf("properly terminating nsrsbc\n");
	return 0;
}

/*
 * Signal handler
 *
 * this one is called asynchronously whevener a registered
 * signal is applied. Just set a flag and don't do any funny
 * things here.
 */
static void sighandler(int sig) {
   if (sig==SIGTERM) exit_program=1;
   if (sig==SIGINT)  exit_program=1;
   return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -