Andrei Pelinescu-Onciul wrote:
On Apr 22, 2008 at 11:03, Alfred E. Heggestad <[EMAIL PROTECTED]> wrote:
Hi

I have added support CRLF ping/pong keepalives aka SIP outbound
style (http://tools.ietf.org/html/draft-ietf-sip-outbound-13).
(thanks to Andrei for guidance).

Thanks a lot for the patch  :-)

The patch is against SER v2.1 and adds a new configuration item
in tcp_options.crlf_ping which is enabled by default.

I don't see how it can be changed from ser.cfg (missing cfg.lex/.y
patch?).

this is now added in the attached patch, as config option "tcp_crlf_ping"

please review the name of this param, if you prefer something else
(like tcp_keep_xyz) then I can change this..



the code works by looking for empty double CRLF's in between
SIP messages, and when detected it will respond with a single
CRLF on the same TCP connection.


I have done some brief testing, but this patch needs much
more heavy testing before it is accepted into CVS (if?)

The patch looks ok to me so please commit it after you add the missing
ser.cfg support. If somehing goes wrong one can always disable it from
ser.cfg and  you'll get your testing :-)
Don't forget to add some entry in the NEWS file.


I added an entry in the NEWS file (see attached patch).

but I do not have commit rights for the root-dir, so I think someone
else needs to commit the patch (if approved) ... :)


/alfred


<snip>
>
Index: NEWS
===================================================================
RCS file: /cvsroot/ser/sip_router/NEWS,v
retrieving revision 1.79
diff -u -3 -r1.79 NEWS
--- NEWS	23 Apr 2008 21:20:43 -0000	1.79
+++ NEWS	24 Apr 2008 12:48:57 -0000
@@ -189,6 +189,8 @@
          keepalive probes, when the previous probe failed. Linux only.
   tcp_keepcnt = number (not set by default) - number of keepalives sent before
          dropping the connection. Linux only.
+  tcp_crlf_ping = yes | no (set by default) - enable CRLF keepalives aka
+         SIP outbound.
   pmtu_discovery = 0 | 1 (default 0) - set DF bit in outbound IP if enabled
   dns_srv_lb = yes | no (default no) - enable dns srv weight based load 
     balancing (see doc/dns.txt)
Index: cfg.lex
===================================================================
RCS file: /cvsroot/ser/sip_router/cfg.lex,v
retrieving revision 1.107
diff -u -3 -r1.107 cfg.lex
--- cfg.lex	17 Apr 2008 16:22:18 -0000	1.107
+++ cfg.lex	24 Apr 2008 12:48:57 -0000
@@ -308,6 +308,7 @@
 TCP_OPT_KEEPIDLE	"tcp_keepidle"
 TCP_OPT_KEEPINTVL	"tcp_keepintvl"
 TCP_OPT_KEEPCNT		"tcp_keepcnt"
+TCP_OPT_CRLF_PING	"tcp_crlf_ping"
 DISABLE_TLS		"disable_tls"|"tls_disable"
 ENABLE_TLS		"enable_tls"|"tls_enable"
 TLSLOG			"tlslog"|"tls_log"
@@ -600,6 +601,8 @@
 									return TCP_OPT_KEEPINTVL; }
 <INITIAL>{TCP_OPT_KEEPCNT}	{ count(); yylval.strval=yytext;
 									return TCP_OPT_KEEPCNT; }
+<INITIAL>{TCP_OPT_CRLF_PING}	{ count(); yylval.strval=yytext;
+									return TCP_OPT_CRLF_PING; }
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
 <INITIAL>{ENABLE_TLS}	{ count(); yylval.strval=yytext; return ENABLE_TLS; }
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
Index: cfg.y
===================================================================
RCS file: /cvsroot/ser/sip_router/cfg.y,v
retrieving revision 1.156
diff -u -3 -r1.156 cfg.y
--- cfg.y	23 Apr 2008 12:55:17 -0000	1.156
+++ cfg.y	24 Apr 2008 12:48:57 -0000
@@ -352,6 +352,7 @@
 %token TCP_OPT_KEEPIDLE
 %token TCP_OPT_KEEPINTVL
 %token TCP_OPT_KEEPCNT
+%token TCP_OPT_CRLF_PING
 %token DISABLE_TLS
 %token ENABLE_TLS
 %token TLSLOG
@@ -907,6 +908,14 @@
 		#endif
 	}
 	| TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
+	| TCP_OPT_CRLF_PING EQUAL NUMBER {
+		#ifdef USE_TCP
+			tcp_options.crlf_ping=$3;
+		#else
+			warn("tcp support not compiled in");
+		#endif
+	}
+	| TCP_OPT_CRLF_PING EQUAL error { yyerror("boolean value expected"); }
 	| DISABLE_TLS EQUAL NUMBER {
 		#ifdef USE_TLS
 			tls_disable=$3;
Index: core_cmd.c
===================================================================
RCS file: /cvsroot/ser/sip_router/core_cmd.c,v
retrieving revision 1.25
diff -u -3 -r1.25 core_cmd.c
--- core_cmd.c	21 Dec 2007 17:58:07 -0000	1.25
+++ core_cmd.c	24 Apr 2008 12:48:58 -0000
@@ -562,7 +562,7 @@
 	if (!tcp_disable){
 		tcp_options_get(&t);
 		rpc->add(c, "{", &handle);
-		rpc->struct_add(handle, "dddddddddddddd",
+		rpc->struct_add(handle, "ddddddddddddddd",
 			"fd_cache",		t.fd_cache,
 			"tcp_buf_write",	t.tcp_buf_write,
 			"tcp_connect_wait",	t.tcp_connect_wait,
@@ -577,7 +577,8 @@
 			"keepalive",	t.keepalive,
 			"keepidle",		t.keepidle,
 			"keepintvl",	t.keepintvl,
-			"keepcnt",		t.keepcnt
+			"keepcnt",		t.keepcnt,
+			"crlf_ping",	t.crlf_ping
 		);
 	}else{
 		rpc->fault(c, 500, "tcp support disabled");
Index: tcp_conn.h
===================================================================
RCS file: /cvsroot/ser/sip_router/tcp_conn.h,v
retrieving revision 1.39
diff -u -3 -r1.39 tcp_conn.h
--- tcp_conn.h	20 Feb 2008 14:37:30 -0000	1.39
+++ tcp_conn.h	24 Apr 2008 12:48:58 -0000
@@ -83,12 +83,13 @@
 
 enum tcp_req_errors {	TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
 						TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
-enum tcp_req_states {	H_SKIP_EMPTY, H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
+enum tcp_req_states {	H_SKIP_EMPTY, H_SKIP_EMPTY_CR_FOUND, H_SKIP_EMPTY_CRLF_FOUND, H_SKIP_EMPTY_CRLFCR_FOUND,
+			H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
 		H_CONT_LEN1, H_CONT_LEN2, H_CONT_LEN3, H_CONT_LEN4, H_CONT_LEN5,
 		H_CONT_LEN6, H_CONT_LEN7, H_CONT_LEN8, H_CONT_LEN9, H_CONT_LEN10,
 		H_CONT_LEN11, H_CONT_LEN12, H_CONT_LEN13, H_L_COLON, 
 		H_CONT_LEN_BODY, H_CONT_LEN_BODY_PARSE,
-		H_STUN_MSG, H_STUN_READ_BODY, H_STUN_FP, H_STUN_END 
+		H_STUN_MSG, H_STUN_READ_BODY, H_STUN_FP, H_STUN_END, H_PING_CRLF
 	};
 
 enum tcp_conn_states { S_CONN_ERROR=-2, S_CONN_BAD=-1, S_CONN_OK=0, 
Index: tcp_options.c
===================================================================
RCS file: /cvsroot/ser/sip_router/tcp_options.c,v
retrieving revision 1.5
diff -u -3 -r1.5 tcp_options.c
--- tcp_options.c	21 Dec 2007 17:58:07 -0000	1.5
+++ tcp_options.c	24 Apr 2008 12:48:58 -0000
@@ -58,6 +58,7 @@
 #ifdef HAVE_TCP_QUICKACK
 	tcp_options.delayed_ack=1;
 #endif
+	tcp_options.crlf_ping=1;
 }
 
 
Index: tcp_options.h
===================================================================
RCS file: /cvsroot/ser/sip_router/tcp_options.h,v
retrieving revision 1.4
diff -u -3 -r1.4 tcp_options.h
--- tcp_options.h	21 Dec 2007 17:58:07 -0000	1.4
+++ tcp_options.h	24 Apr 2008 12:48:58 -0000
@@ -126,6 +126,7 @@
 	int keepidle;   /* idle time (s) before tcp starts sending keepalives */
 	int keepintvl;  /* interval between keep alives */
 	int keepcnt;    /* maximum no. of keepalives before giving up */
+	int crlf_ping;  /* on/off - reply to double CRLF keepalives */
 };
 
 
Index: tcp_read.c
===================================================================
RCS file: /cvsroot/ser/sip_router/tcp_read.c,v
retrieving revision 1.49
diff -u -3 -r1.49 tcp_read.c
--- tcp_read.c	5 Feb 2008 21:47:29 -0000	1.49
+++ tcp_read.c	24 Apr 2008 12:48:58 -0000
@@ -78,6 +78,7 @@
 #include "io_wait.h"
 #include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
 #include "tsend.h"
+#include "forward.h"
 
 #ifdef USE_STUN
 #include "ser_stun.h"
@@ -325,7 +326,13 @@
 			case H_SKIP_EMPTY:
 				switch (*p){
 					case '\n':
+						break;
 					case '\r':
+						if (tcp_options.crlf_ping) {
+							r->state=H_SKIP_EMPTY_CR_FOUND;
+							r->start=p;
+						}
+						break;
 					case ' ':
 					case '\t':
 						/* skip empty lines */
@@ -358,6 +365,36 @@
 				};
 				p++;
 				break;
+
+			case H_SKIP_EMPTY_CR_FOUND:
+				if (*p=='\n'){
+					r->state=H_SKIP_EMPTY_CRLF_FOUND;
+					p++;
+				}else{
+					r->state=H_SKIP_EMPTY;
+				}
+				break;
+
+			case H_SKIP_EMPTY_CRLF_FOUND:
+				if (*p=='\r'){
+					r->state = H_SKIP_EMPTY_CRLFCR_FOUND;
+					p++;
+				}else{
+					r->state = H_SKIP_EMPTY;
+				}
+				break;
+
+			case H_SKIP_EMPTY_CRLFCR_FOUND:
+				if (*p=='\n'){
+					r->state = H_PING_CRLF;
+					r->complete = 1;
+					r->has_content_len = 1; /* hack to avoid error check */
+					p++;
+					goto skip;
+				}else{
+					r->state = H_SKIP_EMPTY;
+				}
+				break;
 #ifdef USE_STUN
 			case H_STUN_MSG:
 				if ((r->pos - r->body) >= sizeof(struct stun_hdr)) {
@@ -539,6 +576,7 @@
 	int resp;
 	long size;
 	struct tcp_req* req;
+	struct dest_info dst;
 	int s;
 	char c;
 	int ret;
@@ -639,6 +677,15 @@
 							   previous char, req->parsed should be ok
 							   because we always alloc BUF_SIZE+1 */
 			*req->parsed=0;
+
+			if (req->state==H_PING_CRLF) {
+				init_dst_from_rcv(&dst, &con->rcv);
+
+				if (tcp_send(&dst, 0, CRLF, CRLF_LEN) < 0) {
+					LOG(L_ERR, "CRLF ping: tcp_send() failed\n");
+				}
+				ret = 0;
+			}else
 #ifdef USE_STUN
 			if (unlikely(req->state==H_STUN_END)){
 				/* stun request */
_______________________________________________
Serdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/serdev

Reply via email to