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 branches found
No related tags found
1 merge request!51xtables-addons: rtsp pause handling with cseq
...@@ -6,12 +6,35 @@ ...@@ -6,12 +6,35 @@
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_nat.h> +#include <net/netfilter/nf_nat.h>
#include "nf_conntrack_rtsp.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++; } #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) +static void rtsp_set_child_ct_timeout(struct nf_conn *master_ct, unsigned int timeout)
+{ +{
+ struct nf_conntrack_tuple_hash *h; + struct nf_conntrack_tuple_hash *h;
...@@ -47,6 +70,12 @@ ...@@ -47,6 +70,12 @@
+#endif +#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, +static void nf_nat_follow_master_nosrc(struct nf_conn *ct,
+ struct nf_conntrack_expect *exp) + struct nf_conntrack_expect *exp)
+{ +{
...@@ -63,22 +92,46 @@ ...@@ -63,22 +92,46 @@
+ nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST); + nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
+} +}
+ +
/* +/*
* Parse an RTSP packet. * 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)) &transoff, &translen))
break; /* not a valid message */ break; /* not a valid message */
+ if(strncmp(pdata+cmdoff, "PAUSE ", 6) == 0) { + info = nfct_help_data(ct);
+ pr_debug("PAUSE handled\n"); + if(strncmp(pdata+cmdoff, "PAUSE ", 6) == 0) {
+ rtsp_set_child_ct_timeout(ct, 3600); + pr_debug("PAUSE handled\n");
+ break; + 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) { if (strncmp(pdata+cmdoff, "TEARDOWN ", 9) == 0) {
pr_debug("teardown handled\n"); pr_debug("teardown handled\n");
remove_rtsp_exp_session(ct); 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, nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
...@@ -92,7 +145,7 @@ ...@@ -92,7 +145,7 @@
if (expinfo.pbtype == pb_range || expinfo.pbtype == pb_discon) { if (expinfo.pbtype == pb_range || expinfo.pbtype == pb_discon) {
pr_debug("setup expectation for rtcp\n"); 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, nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
...@@ -106,7 +159,46 @@ ...@@ -106,7 +159,46 @@
pr_debug("expect_related %pI4:%u-%u-%pI4:%u-%u\n", pr_debug("expect_related %pI4:%u-%u-%pI4:%u-%u\n",
&rtp_exp->tuple.src.u3.ip, &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; srvaddr = expinfo.srvaddr;
...@@ -115,3 +207,18 @@ ...@@ -115,3 +207,18 @@
nf_inet_addr_cmp(&srvaddr, &zeroaddr)) nf_inet_addr_cmp(&srvaddr, &zeroaddr))
continue; continue;
} else } 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