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

📄 sipclient.cpp

📁 KphoneSI (kpsi) is a SIP (Session Initiation Protocol) user agent for Linux, with which you can in
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 // #include <pwd.h>	#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include <qdatetime.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include "../kphone/kphone.h"#include "siputil.h"#include "sipuser.h"#include "sipvia.h"#include "sipcall.h"#include "tcpmessagesocket.h"#include "sipmessage.h"#include "mimecontenttype.h"#include "sipstatus.h"#include "siptransaction.h"#include "sipclient.h"#include "../kphone/kstatics.h"typedef unsigned int u_int;typedef unsigned short u_short;typedef unsigned char u_char;/** @short used by SipClient */struct s_SOA{	char *mname;	char *rname;	u_int serial;	u_int refresh;	u_int retry;	u_int expire;	u_int minimum;};/** @short used by SipClient */struct s_NULL{	char *anything;	u_short length;         /* Length of valid data */};/** @short used by SipClient */struct s_WKS{	struct in_addr address;	char *bitmap;	u_int maplength;	u_char protocol;};/** @short used by SipClient */struct s_HINFO{	char *cpu;	char *os;};/** @short used by SipClient */struct s_MINFO{	char *rmailbx;	char *emailbx;};/** @short used by SipClient */struct s_MX{	char *exchange;	u_short preference;};/** @short used by SipClient */struct s_TXT{	char *text;	struct s_TXT *next;	u_short len;};/** @short used by SipClient */struct s_SRV{	u_short priority;	u_short weight;	u_short port;	char *target;};/** @short used by SipClient */struct s_NAPTR{	u_short order;	u_short pref;	char *flags;	char *service;	char *regexp;	char *replacement;};/** AFS servers used by SipClient */struct s_AFSDB{	u_short subtype;	char *hostname;};/** @short Responsible Person */struct s_RP{	char *mbox_dname;	char *txt_dname;};/** @short ISDN Address */struct s_ISDN{	char *address;	char *sa;    /* optional */};/** @short Route Through */struct s_RT{	u_short preference;	char *int_host;};/** @short Generic RDATA RR structure */union u_rdata{	char *string;            /* Any simple string record */	u_int number;            /* Any simple numeric record */	struct in_addr address; /* Simple address (A record) *//** @short other structured RR types */	struct s_SOA soa;/** @short other structured RR types */	struct s_NULL null;/** @short other structured RR types */	struct s_WKS wks;/** @short other structured RR types */	struct s_HINFO hinfo;/** @short other structured RR types */	struct s_MINFO minfo;/** @short other structured RR types */	struct s_MX mx;/** @short other structured RR types */	struct s_TXT txt;/** @short other structured RR types */	struct s_SRV srv;/** @short other structured RR types */	struct s_NAPTR naptr;/** @short other structured RR types */	struct s_AFSDB afsdb;/** @short other structured RR types */	struct s_RP rp;/** @short other structured RR types */	struct s_ISDN isdn;/** @short other structured RR types */	struct s_RT rt;};/** @short  Full RR structure */typedef struct s_rr{	char *name;	u_short type;	u_short xclass;	u_int ttl;	u_int dlen;	union u_rdata rdata;} s_rr;/** @short  DNS Question sctructure */typedef struct s_question{	char *qname;	u_short qtype;	u_short qclass;} s_question;/** @short  Full DNS message structure */typedef struct s_res_response{	HEADER header;	s_question **question;	s_rr **answer;	s_rr **authority;	s_rr **additional;} res_response;bool const traceMessageSending = true;bool const traceMessageReceived = true;/** Der SipClient*/SipClient::SipClient( QObject *parent, const char *name, unsigned int newListenport,			bool newLooseRoute, bool newStrictRoute, QString socketStr )	: QObject( parent, name ){		debug=KStatics::debugLevel;	if( !setupSocketStuff( newListenport, socketStr ) ) {		printf("=====SipClient::setupSocketStuff() Failed.\n");		exit( 1 );	}	nlp=newListenport;	setupContactUri();	KStatics::myIP = contacturi.getHostname();	useProxyDial = false;	useExplicitProxy = false;	proxyport = 5060;	calls.setAutoDelete( false );	tcpSockets.setAutoDelete( true );	sndSockets.setAutoDelete( true );	fwmode = false;	busymode = false;	user = 0;	hidemode = DontHideVia;	symmetricmode = false;	maxforwards = 0;	looseRoute = newLooseRoute;	strictRoute = newStrictRoute;	testOn = false;	useStunProxy = false;	tcpSocket = 0;	stopStun = false;	foundStun = false;}SipClient::~SipClient( void ){	}void SipClient::setupContactUri( SipUser *user ){	if( user ) {		contacturi.setFullname( user->getUri().getFullname() );		contacturi.setUsername( user->getUri().getUsername() );	}	contacturi.setHostname( Sip::getLocalAddress() );	if( isTcpSocket() ) {		contacturi.setPortNumber( TCP_listener.getPortNumber() );		contacturi.setTransportParam( SipUri::TCP );	} else {		contacturi.setPortNumber( listener.getPortNumber() );		contacturi.setTransportParam( SipUri::UDP );	}}bool SipClient::setupSocketStuff( unsigned int newListenport, QString socketStr ){	unsigned int listenport;	if( socketStr == "UDP" ) {		SocketMode = UDP;	} else {		SocketMode = TCP;	}	if( newListenport ) {		listenport = newListenport;	}	if( listenport == 0 ) {		listenport = 5060;	}	if( isTcpSocket() ) {		listenport = TCP_listener.listen( listenport );		if( !listenport ) { return false; }		TCP_listener.forcePortNumber( listenport );		if(debug>0) printf( "=====SipClient: Listening TCP on port: %d\n", TCP_listener.getPortNumber() );	}        	listenport = listener.listen( listenport );		nlp=listenport;		if( !listenport ) { return false; }		listener.forcePortNumber( listenport );		if(debug>0) printf( "=====SipClient: Listening UDP on port: %d\n", listener.getPortNumber() );		return true;}void SipClient::doSelect( bool block ){	struct timeval timeout;	fd_set read_fds;	int highest_fd;	timeout.tv_sec = 0;	timeout.tv_usec = 5;	FD_ZERO( &read_fds );	FD_SET( listener.getFileDescriptor(), &read_fds );	highest_fd = listener.getFileDescriptor() + 1;retry:	if( select( highest_fd, &read_fds, NULL, NULL, block ? NULL : &timeout ) == -1 ) {		if( errno == EINTR ) goto retry;		printf( "=====SipClient::doSelect(): select() punted" );	}	if( FD_ISSET( listener.getFileDescriptor(), &read_fds ) ) {		incomingMessage( listener.getFileDescriptor(),false );	}if( isTcpSocket() ) {		FD_ZERO( &read_fds );		FD_SET( TCP_listener.getFileDescriptor(), &read_fds );		highest_fd = TCP_listener.getFileDescriptor() + 1;retry2:		if( select( highest_fd, &read_fds, NULL, NULL, block ? NULL : &timeout ) == -1 ) {		 	if( errno == EINTR ) goto retry2; 			    printf( "=====SipClient::doSelect(): select() punted\n" );		}		if( FD_ISSET( TCP_listener.getFileDescriptor(), &read_fds ) ) {			clilen = sizeof(cli_addr);			newsockfd = ::accept( TCP_listener.getFileDescriptor(), (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);						//mark socket to be closed immediately after reading			incomingMessage( newsockfd,true );				}		TCPMessageSocketIterator it( getTcpSocketList() );		for (it.toFirst(); it.current(); ++it) {			tcpSocket = it.current();			if( tcpSocket != 0 ) {				FD_ZERO( &read_fds );				FD_SET( tcpSocket->getFileDescriptor(), &read_fds );				highest_fd = tcpSocket->getFileDescriptor() + 1;retry3:				if( select( highest_fd, &read_fds, NULL, NULL, block ? NULL : &timeout ) == -1 ) {					if( errno == EINTR ) goto retry3;					printf( "=====SipClient::doSelect(): select() punted\n" );				}				if( FD_ISSET( tcpSocket->getFileDescriptor(), &read_fds ) ) {				incomingMessage( tcpSocket->getFileDescriptor(),false );				}			}		}	} else {		auditPending();	}}void SipClient::auditPending( void ){	SipCall *curcall;	SipTransaction *curtrans;	for( curcall = calls.first(); curcall != 0; curcall = calls.next() ) {		for( curtrans = curcall->getTransactionList().first(); curtrans != 0;		     curtrans = curcall->getTransactionList().next() ) {			if( curtrans->auditPending() ) {				return;			}		}	}}void SipClient::incomingMessage( int socketfd,bool closeS ){	QString fullmessage;	char inputbuf[ 8000 ];	int bytesread=1;	int i1,i2,i3,i4;	unsigned int port;	char ip[16];	unsigned int contentLength;	QString lSearch;	int lLen=0;		for(;;) {			// Receive the message		bytesread = read( socketfd, inputbuf, 8000 - 1 );		if( errno == EWOULDBLOCK ) {		    bytesread=0;		    break; 		 }		StunMsgHdr* hdr = reinterpret_cast<StunMsgHdr*>( inputbuf );		if( hdr->msgType == BindResponseMsg ) {				// check that the size of the header isn't larger than what we've read				if ((signed int)sizeof(StunMsgHdr) > bytesread)				{					printf("=====Malformed packet (sizeof(StunMsgHdr) > bytesread)\n");					return;				}				char* body = inputbuf + sizeof( StunMsgHdr );				unsigned int size = ntohs( hdr->msgLength );				port = listener.getPortNumber();				while( size > 0 ) {					StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>( body );					unsigned int hdrLen = ntohs( attr->length );					// check that our attribute length is not larger than the remaining size					if (hdrLen+4 > size)					{						printf("!!!!!Malformed packet (hdrLen+4 > size)\n");						return;					}					if( ntohs( attr->type ) == MappedAddress ) {						StunAtrAddress* attribute = reinterpret_cast<StunAtrAddress*>( body );						if ( attribute->address.addrHdr.family == IPv4Family ) {							StunAtrAddress4* atrAdd4 = reinterpret_cast<StunAtrAddress4*>( body );							if ( hdrLen == sizeof( StunAtrAddress4 ) - 4 ) {								port = ntohs( atrAdd4->addrHdr.port );								i1 = atrAdd4->v4addr & 0xFF;								i2 = (atrAdd4->v4addr & 0xFF00) >> 8;								i3 = (atrAdd4->v4addr & 0xFF0000) >> 16;								i4 = (atrAdd4->v4addr & 0xFF000000) >> 24;								sprintf( ip, "%d.%d.%d.%d", i1, i2, i3, i4 );								if(debug >0) printf( "======SipCient (%s:%d) : STUN response %s:%d\n", Sip::getLocalAddress().latin1(),nlp,ip,port );							}						}					}					body += hdrLen+4;					size -= hdrLen+4;				}				SipRegister *current;				if( !QString(ip).contains( Sip::getLocalAddress() ) ||						listener.getPortNumber() != port ) {					Sip::setLocalAddress( ip );					foundStun=true;						listener.forcePortNumber( port );					setupContactUri();					QPtrListIterator<SipRegister> reg = user->getSipRegisterList();					for( ; reg.current(); ++reg ) {						current = reg.current();						if( current->getRegisterState() == SipRegister::Connected ||						current->getAutoRegister() ) {							current->setAutoRegister( false );							current->requestRegister();						}					}				} else {					QPtrListIterator<SipRegister> reg = user->getSipRegisterList();					for( ; reg.current(); ++reg ) {						current = reg.current();						if( current->getAutoRegister() ) {							current->setAutoRegister( false );							current->requestRegister();						}					}				}				return;		}  else if( haveNoMoreStun() ) {			foundStun=false;			SipRegister *current;			Sip::setLocalAddress( 0 );			int listenport = listener.listen( nlp );			nlp=listenport;			listener.forcePortNumber( listenport );			setupContactUri();			QPtrListIterator<SipRegister> reg = user->getSipRegisterList();			for( ; reg.current(); ++reg ) {				current = reg.current();				if( current->getRegisterState() == SipRegister::Connected ||				current->getAutoRegister() ) {					current->setAutoRegister( false );					current->requestRegister();					}			}

⌨️ 快捷键说明

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