/test/jssipsite/lib/sanityCheck.js
https://gitlab.com/Nowsad.kamrul/cthealthltd · JavaScript · 225 lines · 153 code · 35 blank · 37 comment · 30 complexity · 92613fb9aab710969b758e02ffa22d7f MD5 · raw file
- module.exports = sanityCheck;
- /**
- * Dependencies.
- */
- var debug = require('debug')('JsSIP:sanityCheck');
- var JsSIP_C = require('./Constants');
- var SIPMessage = require('./SIPMessage');
- var Utils = require('./Utils');
- var message, ua, transport,
- requests = [],
- responses = [],
- all = [];
- requests.push(rfc3261_8_2_2_1);
- requests.push(rfc3261_16_3_4);
- requests.push(rfc3261_18_3_request);
- requests.push(rfc3261_8_2_2_2);
- responses.push(rfc3261_8_1_3_3);
- responses.push(rfc3261_18_3_response);
- all.push(minimumHeaders);
- function sanityCheck(m, u, t) {
- var len, pass;
- message = m;
- ua = u;
- transport = t;
- len = all.length;
- while(len--) {
- pass = all[len](message);
- if(pass === false) {
- return false;
- }
- }
- if(message instanceof SIPMessage.IncomingRequest) {
- len = requests.length;
- while(len--) {
- pass = requests[len](message);
- if(pass === false) {
- return false;
- }
- }
- }
- else if(message instanceof SIPMessage.IncomingResponse) {
- len = responses.length;
- while(len--) {
- pass = responses[len](message);
- if(pass === false) {
- return false;
- }
- }
- }
- //Everything is OK
- return true;
- }
- /*
- * Sanity Check for incoming Messages
- *
- * Requests:
- * - _rfc3261_8_2_2_1_ Receive a Request with a non supported URI scheme
- * - _rfc3261_16_3_4_ Receive a Request already sent by us
- * Does not look at via sent-by but at jssip_id, which is inserted as
- * a prefix in all initial requests generated by the ua
- * - _rfc3261_18_3_request_ Body Content-Length
- * - _rfc3261_8_2_2_2_ Merged Requests
- *
- * Responses:
- * - _rfc3261_8_1_3_3_ Multiple Via headers
- * - _rfc3261_18_3_response_ Body Content-Length
- *
- * All:
- * - Minimum headers in a SIP message
- */
- // Sanity Check functions for requests
- function rfc3261_8_2_2_1() {
- if(message.s('to').uri.scheme !== 'sip') {
- reply(416);
- return false;
- }
- }
- function rfc3261_16_3_4() {
- if(!message.to_tag) {
- if(message.call_id.substr(0, 5) === ua.configuration.jssip_id) {
- reply(482);
- return false;
- }
- }
- }
- function rfc3261_18_3_request() {
- var len = Utils.str_utf8_length(message.body),
- contentLength = message.getHeader('content-length');
- if(len < contentLength) {
- reply(400);
- return false;
- }
- }
- function rfc3261_8_2_2_2() {
- var tr, idx,
- fromTag = message.from_tag,
- call_id = message.call_id,
- cseq = message.cseq;
- // Accept any in-dialog request.
- if(message.to_tag) {
- return;
- }
- // INVITE request.
- if (message.method === JsSIP_C.INVITE) {
- // If the branch matches the key of any IST then assume it is a retransmission
- // and ignore the INVITE.
- // TODO: we should reply the last response.
- if (ua.transactions.ist[message.via_branch]) {
- return false;
- }
- // Otherwise check whether it is a merged request.
- else {
- for(idx in ua.transactions.ist) {
- tr = ua.transactions.ist[idx];
- if(tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
- reply(482);
- return false;
- }
- }
- }
- }
- // Non INVITE request.
- else {
- // If the branch matches the key of any NIST then assume it is a retransmission
- // and ignore the request.
- // TODO: we should reply the last response.
- if (ua.transactions.nist[message.via_branch]) {
- return false;
- }
- // Otherwise check whether it is a merged request.
- else {
- for(idx in ua.transactions.nist) {
- tr = ua.transactions.nist[idx];
- if(tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
- reply(482);
- return false;
- }
- }
- }
- }
- }
- // Sanity Check functions for responses
- function rfc3261_8_1_3_3() {
- if(message.getHeaders('via').length > 1) {
- debug('more than one Via header field present in the response, dropping the response');
- return false;
- }
- }
- function rfc3261_18_3_response() {
- var
- len = Utils.str_utf8_length(message.body),
- contentLength = message.getHeader('content-length');
- if(len < contentLength) {
- debug('message body length is lower than the value in Content-Length header field, dropping the response');
- return false;
- }
- }
- // Sanity Check functions for requests and responses
- function minimumHeaders() {
- var
- mandatoryHeaders = ['from', 'to', 'call_id', 'cseq', 'via'],
- idx = mandatoryHeaders.length;
- while(idx--) {
- if(!message.hasHeader(mandatoryHeaders[idx])) {
- debug('missing mandatory header field : ' + mandatoryHeaders[idx] + ', dropping the response');
- return false;
- }
- }
- }
- // Reply
- function reply(status_code) {
- var to,
- response = 'SIP/2.0 ' + status_code + ' ' + JsSIP_C.REASON_PHRASE[status_code] + '\r\n',
- vias = message.getHeaders('via'),
- length = vias.length,
- idx = 0;
- for(idx; idx < length; idx++) {
- response += 'Via: ' + vias[idx] + '\r\n';
- }
- to = message.getHeader('To');
- if(!message.to_tag) {
- to += ';tag=' + Utils.newTag();
- }
- response += 'To: ' + to + '\r\n';
- response += 'From: ' + message.getHeader('From') + '\r\n';
- response += 'Call-ID: ' + message.call_id + '\r\n';
- response += 'CSeq: ' + message.cseq + ' ' + message.method + '\r\n';
- response += '\r\n';
- transport.send(response);
- }