2
0
Эх сурвалжийг харах

* Added parsing of Refer-To header.

Juha Heinanen 20 жил өмнө
parent
commit
8b482f1a5f

+ 46 - 0
parser/case_refe.h

@@ -0,0 +1,46 @@
+/* 
+ * Refer-To Header Field Name Parsing Macros
+ *
+ * Copyright (C) 2005 Juha Heinanen
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef CASE_REFE_H
+#define CASE_REFE_H
+
+#define r_to_CASE                          \
+        if (LOWER_DWORD(val) == _r_to_) {  \
+                hdr->type = HDR_REFER_TO;  \
+                p += 4;                    \
+                goto dc_end;               \
+        }
+
+
+#define refe_CASE      \
+     p += 4;           \
+     val = READ(p);    \
+     r_to_CASE;         \
+     goto other;
+
+
+#endif /* CASE_REFE_H */

+ 4 - 0
parser/hf.c

@@ -158,6 +158,10 @@ void clean_hdr_field(struct hdr_field* hf)
 			free_to(hf->parsed);
 			free_to(hf->parsed);
 			break;
 			break;
 
 
+		case HDR_REFER_TO:
+			free_to(hf->parsed);
+			break;
+
 		default:
 		default:
 			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
 			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
 			    hf->type);
 			    hf->type);

+ 3 - 2
parser/hf.h

@@ -73,14 +73,15 @@
 #define HDR_CONTENTDISPOSITION (1 << 27)  /* Content-Disposition hdr field */
 #define HDR_CONTENTDISPOSITION (1 << 27)  /* Content-Disposition hdr field */
 #define HDR_DIVERSION          (1 << 28)  /* Diversion header field */
 #define HDR_DIVERSION          (1 << 28)  /* Diversion header field */
 #define HDR_RPID               (1 << 29)  /* Remote-Party-ID header field */
 #define HDR_RPID               (1 << 29)  /* Remote-Party-ID header field */
-#define HDR_OTHER              (1 << 30)  /* Some other header field */
+#define HDR_REFER_TO           (1 << 30)  /* Remote-Party-ID header field */
+#define HDR_OTHER              (1 << 31)  /* Some other header field */
 
 
 
 
 /* returns true if the header links allocated memory on parse field */
 /* returns true if the header links allocated memory on parse field */
 #define hdr_allocs_parse( _hdr ) \
 #define hdr_allocs_parse( _hdr ) \
 	(((_hdr)->type)&(HDR_VIA|HDR_TO|HDR_FROM|HDR_CONTACT|HDR_ROUTE|\
 	(((_hdr)->type)&(HDR_VIA|HDR_TO|HDR_FROM|HDR_CONTACT|HDR_ROUTE|\
 		HDR_RECORDROUTE|HDR_AUTHORIZATION|HDR_EXPIRES|HDR_PROXYAUTH|\
 		HDR_RECORDROUTE|HDR_AUTHORIZATION|HDR_EXPIRES|HDR_PROXYAUTH|\
-		HDR_EVENT|HDR_ACCEPT|HDR_CONTENTDISPOSITION|HDR_DIVERSION|HDR_RPID))
+		HDR_EVENT|HDR_ACCEPT|HDR_CONTENTDISPOSITION|HDR_DIVERSION|HDR_RPID|HDR_REFER_TO))
 
 
 
 
 
 

+ 3 - 0
parser/keys.h

@@ -125,4 +125,7 @@
 #define __id2_ 0x2064692d   /* "-id " */
 #define __id2_ 0x2064692d   /* "-id " */
 #define __id1_ 0x3a64692d   /* "-id:" */
 #define __id1_ 0x3a64692d   /* "-id:" */
 
 
+#define _refe_ 0x65666572   /* "refe" */
+#define _r_to_ 0x6f742d72   /* "r-to" */
+
 #endif /* KEYS_H */
 #endif /* KEYS_H */

+ 5 - 0
parser/msg_parser.c

@@ -204,6 +204,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 	        case HDR_ACCEPTDISPOSITION:
 	        case HDR_ACCEPTDISPOSITION:
 	        case HDR_DIVERSION:
 	        case HDR_DIVERSION:
 	        case HDR_RPID:
 	        case HDR_RPID:
+	        case HDR_REFER_TO:
 		case HDR_OTHER:
 		case HDR_OTHER:
 			/* just skip over it */
 			/* just skip over it */
 			hdr->body.s=tmp;
 			hdr->body.s=tmp;
@@ -407,6 +408,10 @@ int parse_headers(struct sip_msg* msg, int flags, int next)
 				if (msg->rpid==0) msg->rpid = hf;
 				if (msg->rpid==0) msg->rpid = hf;
 				msg->parsed_flag|=HDR_RPID;
 				msg->parsed_flag|=HDR_RPID;
 				break;
 				break;
+		        case HDR_REFER_TO:
+				if (msg->refer_to==0) msg->refer_to = hf;
+				msg->parsed_flag|=HDR_REFER_TO;
+				break;
 			case HDR_VIA:
 			case HDR_VIA:
 				msg->parsed_flag|=HDR_VIA;
 				msg->parsed_flag|=HDR_VIA;
 				DBG("parse_headers: Via found, flags=%d\n", flags);
 				DBG("parse_headers: Via found, flags=%d\n", flags);

+ 1 - 0
parser/msg_parser.h

@@ -194,6 +194,7 @@ struct sip_msg {
 	struct hdr_field* accept_disposition;
 	struct hdr_field* accept_disposition;
 	struct hdr_field* diversion;
 	struct hdr_field* diversion;
 	struct hdr_field* rpid;
 	struct hdr_field* rpid;
+        struct hdr_field* refer_to;
 
 
 	char* eoh;        /* pointer to the end of header (if found) or null */
 	char* eoh;        /* pointer to the end of header (if found) or null */
 	char* unparsed;   /* here we stopped parsing*/
 	char* unparsed;   /* here we stopped parsing*/

+ 3 - 1
parser/parse_hname2.c

@@ -84,6 +84,7 @@ static inline char* skip_ws(char* p, unsigned int size)
 #include "case_supp.h"     /* Supported */
 #include "case_supp.h"     /* Supported */
 #include "case_dive.h"     /* Diversion */
 #include "case_dive.h"     /* Diversion */
 #include "case_remo.h"     /* Remote-Party-ID */
 #include "case_remo.h"     /* Remote-Party-ID */
+#include "case_refe.h"     /* Refer-To */
 
 
 
 
 #define READ(val) \
 #define READ(val) \
@@ -114,7 +115,8 @@ static inline char* skip_ws(char* p, unsigned int size)
         case _subj_: subj_CASE; \
         case _subj_: subj_CASE; \
         case _user_: user_CASE; \
         case _user_: user_CASE; \
         case _dive_: dive_CASE; \
         case _dive_: dive_CASE; \
-        case _remo_: remo_CASE;
+        case _remo_: remo_CASE; \
+        case _refe_: refe_CASE;
 
 
 
 
 #define PARSE_COMPACT(id)          \
 #define PARSE_COMPACT(id)          \

+ 79 - 0
parser/parse_refer_to.c

@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005 Juha Heinanen
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ 
+#include "parse_from.h"
+#include "parse_to.h"
+#include <stdlib.h>
+#include <string.h>
+#include "../dprint.h"
+#include "msg_parser.h"
+#include "../ut.h"
+#include "../mem/mem.h"
+
+ 
+/*
+ * This method is used to parse Refer-To header.
+ *
+ * params: msg : sip msg
+ * returns 0 on success,
+ *        -1 on failure.
+ */
+int parse_refer_to_header( struct sip_msg *msg )
+{
+	struct to_body* refer_to_b;
+	
+ 	if ( !msg->refer_to &&
+	     (parse_headers(msg, HDR_REFER_TO,0)==-1 || !msg->refer_to)) {
+ 		goto error;
+ 	}
+ 
+ 	/* maybe the header is already parsed! */
+ 	if (msg->refer_to->parsed)
+ 		return 0;
+ 
+ 	/* bad luck! :-( - we have to parse it */
+ 	/* first, get some memory */
+ 	refer_to_b = pkg_malloc(sizeof(struct to_body));
+ 	if (refer_to_b == 0) {
+ 		LOG(L_ERR, "ERROR:parse_refer_to_header: out of pkg_memory\n");
+ 		goto error;
+ 	}
+ 
+ 	/* now parse it!! */
+ 	memset(refer_to_b, 0, sizeof(struct to_body));
+ 	parse_to(msg->refer_to->body.s,
+		 msg->refer_to->body.s + msg->refer_to->body.len+1,
+		 refer_to_b);
+ 	if (refer_to_b->error == PARSE_ERROR) {
+ 		LOG(L_ERR, "ERROR:parse_refer_to_header: bad Refer-To header\n");
+ 		pkg_free(refer_to_b);
+ 		goto error;
+ 	}
+ 	msg->refer_to->parsed = refer_to_b;
+ 
+ 	return 0;
+ error:
+ 	return -1;
+}

+ 42 - 0
parser/parse_refer_to.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005 Juha Heinanen
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ 
+ 
+#ifndef PARSE_REFER_TO_H
+#define PARSE_REFER_TO_H
+ 
+#include "msg_parser.h"
+ 
+ 
+/* casting macro for accessing Refer-To body */
+#define get_refer_to(p_msg)  ((struct to_body*)(p_msg)->refer_to->parsed)
+
+
+/*
+ * Refer-To header field parser
+ */
+int parse_refer_to_header( struct sip_msg *msg);
+ 
+#endif /* PARSE_REFER_TO_H */