Skip to content
Snippets Groups Projects
Commit 77fb9b2a authored by Amit Kumar's avatar Amit Kumar Committed by Rahul Thakur
Browse files

xtables-addons: rtsp pause handling with cseq

child expect entry timeout value set handled
in the response message of PAUSE with condition
verification of cseq value.
parent 35805e52
No related tags found
1 merge request!51xtables-addons: rtsp pause handling with cseq
......@@ -6,12 +6,35 @@
#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_nat.h>
#include "nf_conntrack_rtsp.h"
#define NF_NEED_STRNCASECMP
@@ -110,6 +111,57 @@ EXPORT_SYMBOL_GPL(nf_nat_rtsp_hook);
#define NF_NEED_STRNCASECMP
@@ -111,6 +112,87 @@ EXPORT_SYMBOL_GPL(nf_nat_rtsp_hook);
#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
/*
+ * Get the seq number of RTSP message
+ * Parameters:
+ * IN str pointer to rtsp message pointing to seq number
+*/
+static int rtsp_get_cseq(const char *str)
+{
+ unsigned long cseq = 0, i = 0;
+ char c = *str;
+ while(i++ < 10 && c && c != 0xd && c>='0' && c <= '9'){
+ cseq = (cseq * 10) + (c - '0');
+ c = *(str + i);
+ }
+ if(!cseq)
+ cseq = -1;
+ return (int) cseq;
+}
+
+/*
+ * set timeout value for the expect entry of all child conntrack
+ * Parameters:
+ * IN master_ct conntrack entry point as parent
+ * IN timeout timeout value to timeout value to set for child
+*/
+static void rtsp_set_child_ct_timeout(struct nf_conn *master_ct, unsigned int timeout)
+{
+ struct nf_conntrack_tuple_hash *h;
......@@ -47,6 +70,12 @@
+#endif
+}
+
+/*
+ * callback function that set conntrack matching flag
+ * Parameters:
+ * IN ct conntrack pointer
+ * IN exp expect entry pointer
+*/
+static void nf_nat_follow_master_nosrc(struct nf_conn *ct,
+ struct nf_conntrack_expect *exp)
+{
......@@ -63,22 +92,46 @@
+ nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
+}
+
/*
+/*
* Parse an RTSP packet.
*
@@ -395,6 +447,11 @@ help_out(struct sk_buff *skb, unsigned c
* Returns zero if parsing failed.
@@ -367,6 +449,8 @@ help_out(struct sk_buff *skb, unsigned c
//uint datalen = tcplen - tcph->doff * 4;
uint dataoff = 0;
int ret = NF_ACCEPT;
+ int cseq = 0;
+ struct nf_ct_rtsp_info *info = NULL;
struct nf_conntrack_expect *rtp_exp;
struct nf_conntrack_expect *rtcp_exp = NULL;
@@ -395,6 +479,25 @@ help_out(struct sk_buff *skb, unsigned c
&transoff, &translen))
break; /* not a valid message */
+ if(strncmp(pdata+cmdoff, "PAUSE ", 6) == 0) {
+ pr_debug("PAUSE handled\n");
+ rtsp_set_child_ct_timeout(ct, 3600);
+ break;
+ }
+ info = nfct_help_data(ct);
+ if(strncmp(pdata+cmdoff, "PAUSE ", 6) == 0) {
+ pr_debug("PAUSE handled\n");
+ cseq = strncmp(pdata+cseqoff, "CSeq: ", 6);
+ if(cseq == -1) {
+ cseq = strncmp(pdata+cseqoff, "Cseq: ", 6);
+ if(cseq == -1) {
+ pr_debug("nf_ct_rtsp: wrong PAUSE msg\n");
+ } else {
+ cseq = rtsp_get_cseq(pdata+cseqoff+cseq+6);
+ }
+ } else {
+ cseq = rtsp_get_cseq(pdata+cseqoff+cseq+6);
+ }
+ info->paused = cseq;
+ break;
+ } else
+ info->paused = 0;
+
if (strncmp(pdata+cmdoff, "TEARDOWN ", 9) == 0) {
pr_debug("teardown handled\n");
remove_rtsp_exp_session(ct);
@@ -454,11 +511,12 @@ help_out(struct sk_buff *skb, unsigned c
@@ -454,11 +557,12 @@ help_out(struct sk_buff *skb, unsigned c
}
nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
......@@ -92,7 +145,7 @@
if (expinfo.pbtype == pb_range || expinfo.pbtype == pb_discon) {
pr_debug("setup expectation for rtcp\n");
@@ -471,11 +529,12 @@ help_out(struct sk_buff *skb, unsigned c
@@ -471,11 +575,12 @@ help_out(struct sk_buff *skb, unsigned c
}
nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
......@@ -106,7 +159,46 @@
pr_debug("expect_related %pI4:%u-%u-%pI4:%u-%u\n",
&rtp_exp->tuple.src.u3.ip,
@@ -575,7 +634,7 @@ help_in(struct sk_buff *skb, unsigned ch
@@ -547,6 +652,9 @@ help_in(struct sk_buff *skb, unsigned ch
struct nf_conntrack_expect *exp_ct = NULL;
struct nf_conntrack_tuple t;
struct net *net = nf_ct_net(ct);
+ struct nf_ct_rtsp_info *info = NULL;
+ int cseq = 0;
+ char *cseq_p = NULL;
memset(&expinfo, 0, sizeof(expinfo));
@@ -559,6 +667,28 @@ help_in(struct sk_buff *skb, unsigned ch
uint transoff = 0;
uint translen = 0;
+ info = nfct_help_data(ct);
+ /* Response to a previous PAUSE message */
+ if (info->paused) {
+ cseq_p = strstr(pdata+cmdoff, "CSeq: ");
+ if(cseq_p == NULL) {
+ cseq_p = strstr(pdata+cmdoff, "Cseq: ");
+ if(cseq_p == NULL) {
+ pr_debug("nf_ct_rtsp: wrong reply msg\n");
+ } else {
+ cseq = rtsp_get_cseq(cseq_p + 6);
+ }
+ } else {
+ cseq = rtsp_get_cseq(cseq_p + 6);
+ }
+ if(cseq == info->paused) {
+ pr_debug("nf_ct_rtsp: Reply to PAUSE\n");
+ rtsp_set_child_ct_timeout(ct, 3600);
+ info->paused = 0;
+ goto out;
+ }
+ }
+
if (!rtsp_parse_message(pdata, datalen, &dataoff,
&hdrsoff, &hdrslen,
&cseqoff, &cseqlen,
@@ -575,7 +705,7 @@ help_in(struct sk_buff *skb, unsigned ch
srvaddr = expinfo.srvaddr;
......@@ -115,3 +207,18 @@
nf_inet_addr_cmp(&srvaddr, &zeroaddr))
continue;
} else
--- a/extensions/rtsp/nf_conntrack_rtsp.h
+++ b/extensions/rtsp/nf_conntrack_rtsp.h
@@ -28,6 +28,12 @@ typedef enum {
pb_discon /* client_port=x/y (rtspbis) */
} portblock_t;
+/* record to keep seq number for pause message sent from client */
+struct nf_ct_rtsp_info {
+ /* set when the client has sent PAUSE message and not replied */
+ int paused;
+};
+
/* We record seq number and length of rtsp headers here, all in host order. */
/*
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment