Переглянути джерело

core: unified function for returning string of a protocol

- returns variants for uppercase and lowecase, representation for uri or
  bare proto: udp, tcp, tls, sctp, ws and wss
- in uri, PROTO_WS and PROTO_WSS are represented as transport=ws
Daniel-Constantin Mierla 10 роки тому
батько
коміт
b81dff6aba
4 змінених файлів з 138 додано та 14 видалено
  1. 48 13
      ip_addr.c
  2. 2 1
      ip_addr.h
  3. 83 0
      parser/msg_parser.c
  4. 5 0
      parser/msg_parser.h

+ 48 - 13
ip_addr.c

@@ -307,7 +307,50 @@ int is_mcast(struct ip_addr* ip)
 
 #endif /* USE_MCAST */
 
-
+/** get string for known protocols.
+ * @param iproto - protocol number
+ * @param utype  - 1 if result is used for URI, or 0
+ * @param vtype  - 1 if result is wanted uppercase, or 0 for lowercase
+ * @param sproto - the string for the proto
+ * @return  0 if it is a valid and supported protocol, negative otherwise
+ */
+int get_valid_proto_string(unsigned int iproto, int utype, int vtype,
+		str *sproto)
+{
+	switch(iproto){
+		case PROTO_NONE:
+			return -1;
+		case PROTO_UDP:
+			sproto->len = 3;
+			sproto->s = (vtype)?"UDP":"udp";
+			return 0;
+		case PROTO_TCP:
+			sproto->len = 3;
+			sproto->s = (vtype)?"TCP":"tcp";
+			return 0;
+		case PROTO_TLS:
+			sproto->len = 3;
+			sproto->s = (vtype)?"TLS":"tls";
+			return 0;
+		case PROTO_SCTP:
+			sproto->len = 4;
+			sproto->s = (vtype)?"SCTP":"sctp";
+			return 0;
+		case PROTO_WS:
+		case PROTO_WSS:
+			if(iproto==PROTO_WS || utype) {
+				/* ws-only in SIP URI */
+				sproto->len = 2;
+				sproto->s = (vtype)?"WS":"ws";
+			} else {
+				sproto->len = 3;
+				sproto->s = (vtype)?"WSS":"wss";
+			}
+			return 0;
+		default:
+			return -2;
+	}
+}
 
 /** get protocol name (asciiz).
  * @param proto - protocol number
@@ -315,22 +358,14 @@ int is_mcast(struct ip_addr* ip)
  */
 char* get_proto_name(unsigned int proto)
 {
+	str sproto;
 	switch(proto){
 		case PROTO_NONE:
 			return "*";
-		case PROTO_UDP:
-			return "udp";
-		case PROTO_TCP:
-			return "tcp";
-		case PROTO_TLS:
-			return "tls";
-		case PROTO_SCTP:
-			return "sctp";
-		case PROTO_WS:
-		case PROTO_WSS:
-			return "ws";
 		default:
-			return "unknown";
+			if(get_valid_proto_string(proto, 1, 0, &sproto)<0)
+				return "unknown";
+			return sproto.s;
 	}
 }
 

+ 2 - 1
ip_addr.h

@@ -245,7 +245,8 @@ void print_net(struct net* net);
 char* get_proto_name(unsigned int proto);
 #define proto2a get_proto_name
 
-
+int get_valid_proto_string(unsigned int iproto, int utype, int vtype,
+		str *sproto);
 
 #ifdef USE_MCAST
 /* Returns 1 if the given address is a multicast address */

+ 83 - 0
parser/msg_parser.c

@@ -1033,3 +1033,86 @@ int msg_set_time(sip_msg_t* const msg)
 		return 0;
 	return gettimeofday(&msg->tval, NULL);
 }
+
+/**
+ * get source ip, port and protocol in SIP URI format
+ * - tmode - 0: short format (transport=udp is not added, being default)
+ */
+int get_src_uri(sip_msg_t *m, int tmode, str *uri)
+{
+	static char buf[MAX_URI_SIZE];
+	char* p;
+	str ip, port;
+	int len;
+	str proto;
+
+	if (!uri || !m) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	if(tmode==0) {
+		switch(m->rcv.proto) {
+			case PROTO_NONE:
+			case PROTO_UDP:
+				proto.s = 0; /* Do not add transport parameter, UDP is default */
+				proto.len = 0;
+			break;
+			default:
+				if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto)<0) {
+					LM_ERR("unknown transport protocol\n");
+					return -1;
+				}
+		}
+	} else {
+		if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto)<0) {
+			LM_ERR("unknown transport protocol\n");
+			return -1;
+		}
+	}
+
+	ip.s = ip_addr2a(&m->rcv.src_ip);
+	ip.len = strlen(ip.s);
+
+	port.s = int2str(m->rcv.src_port, &port.len);
+
+	len = 4 + ip.len + 2*(m->rcv.src_ip.af==AF_INET6)+ 1 + port.len;
+	if (proto.s) {
+		len += TRANSPORT_PARAM_LEN;
+		len += proto.len;
+	}
+
+	if (len > MAX_URI_SIZE) {
+		LM_ERR("buffer too small\n");
+		return -1;
+	}
+
+	p = buf;
+	memcpy(p, "sip:", 4);
+	p += 4;
+
+	if (m->rcv.src_ip.af==AF_INET6)
+		*p++ = '[';
+	memcpy(p, ip.s, ip.len);
+	p += ip.len;
+	if (m->rcv.src_ip.af==AF_INET6)
+		*p++ = ']';
+
+	*p++ = ':';
+
+	memcpy(p, port.s, port.len);
+	p += port.len;
+
+	if (proto.s) {
+		memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN);
+		p += TRANSPORT_PARAM_LEN;
+
+		memcpy(p, proto.s, proto.len);
+		p += proto.len;
+	}
+
+	uri->s = buf;
+	uri->len = len;
+
+	return 0;
+}

+ 5 - 0
parser/msg_parser.h

@@ -521,4 +521,9 @@ int msg_set_time(sip_msg_t* const msg);
  */
 void msg_ldata_reset(sip_msg_t*);
 
+/**
+ * get source ip, port and protocol in SIP URI format
+ */
+int get_src_uri(sip_msg_t *m, int tmode, str *uri);
+
 #endif