From a81876e6efa68d561039de86d67b415525e4851d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 25 Mar 2008 20:24:04 -0700 Subject: [PATCH] --- yaml --- r: 90356 b: refs/heads/master c: 9467ee380ae881443bc259fbbac9992baf523e2d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/net/netfilter/nf_conntrack_sip.c | 52 ++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 2ac0449edda8..949bffad8da5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 595a8ecb5fa41295a7010678b60cb2f7ab15fe42 +refs/heads/master: 9467ee380ae881443bc259fbbac9992baf523e2d diff --git a/trunk/net/netfilter/nf_conntrack_sip.c b/trunk/net/netfilter/nf_conntrack_sip.c index 71f744ad7653..8e7e5b465ffb 100644 --- a/trunk/net/netfilter/nf_conntrack_sip.c +++ b/trunk/net/netfilter/nf_conntrack_sip.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -533,6 +534,22 @@ int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr, } EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header); +static void flush_expectations(struct nf_conn *ct) +{ + struct nf_conn_help *help = nfct_help(ct); + struct nf_conntrack_expect *exp; + struct hlist_node *n, *next; + + spin_lock_bh(&nf_conntrack_lock); + hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) { + if (!del_timer(&exp->timeout)) + continue; + nf_ct_unlink_expect(exp); + nf_ct_expect_put(exp); + } + spin_unlock_bh(&nf_conntrack_lock); +} + static int set_expected_rtp(struct sk_buff *skb, const char **dptr, unsigned int *datalen, union nf_inet_addr *addr, __be16 port) @@ -606,32 +623,58 @@ static int process_invite_response(struct sk_buff *skb, const char **dptr, unsigned int *datalen, unsigned int cseq, unsigned int code) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dptr, datalen, cseq); - - return NF_ACCEPT; + else { + flush_expectations(ct); + return NF_ACCEPT; + } } static int process_update_response(struct sk_buff *skb, const char **dptr, unsigned int *datalen, unsigned int cseq, unsigned int code) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dptr, datalen, cseq); - - return NF_ACCEPT; + else { + flush_expectations(ct); + return NF_ACCEPT; + } } static int process_prack_response(struct sk_buff *skb, const char **dptr, unsigned int *datalen, unsigned int cseq, unsigned int code) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dptr, datalen, cseq); + else { + flush_expectations(ct); + return NF_ACCEPT; + } +} + +static int process_bye_request(struct sk_buff *skb, + const char **dptr, unsigned int *datalen, + unsigned int cseq) +{ + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + flush_expectations(ct); return NF_ACCEPT; } @@ -640,6 +683,7 @@ static const struct sip_handler sip_handlers[] = { SIP_HANDLER("UPDATE", process_sdp, process_update_response), SIP_HANDLER("ACK", process_sdp, NULL), SIP_HANDLER("PRACK", process_sdp, process_prack_response), + SIP_HANDLER("BYE", process_bye_request, NULL), }; static int process_sip_response(struct sk_buff *skb,