diff options
author | Patrick McHardy <kaber@trash.net> | 2008-03-25 23:24:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-25 23:24:04 -0400 |
commit | 9467ee380ae881443bc259fbbac9992baf523e2d (patch) | |
tree | 29fc53175dc0e5b244c27e1a9374c17cd611ca64 | |
parent | 595a8ecb5fa41295a7010678b60cb2f7ab15fe42 (diff) |
[NETFILTER]: nf_conntrack_sip: flush expectations on call termination
Flush the RTP expectations we've created when a call is hung up or
terminated otherwise.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 71f744ad7653..8e7e5b465ffb 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/netfilter.h> | 17 | #include <linux/netfilter.h> |
18 | 18 | ||
19 | #include <net/netfilter/nf_conntrack.h> | 19 | #include <net/netfilter/nf_conntrack.h> |
20 | #include <net/netfilter/nf_conntrack_core.h> | ||
20 | #include <net/netfilter/nf_conntrack_expect.h> | 21 | #include <net/netfilter/nf_conntrack_expect.h> |
21 | #include <net/netfilter/nf_conntrack_helper.h> | 22 | #include <net/netfilter/nf_conntrack_helper.h> |
22 | #include <linux/netfilter/nf_conntrack_sip.h> | 23 | #include <linux/netfilter/nf_conntrack_sip.h> |
@@ -533,6 +534,22 @@ int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr, | |||
533 | } | 534 | } |
534 | EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header); | 535 | EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header); |
535 | 536 | ||
537 | static void flush_expectations(struct nf_conn *ct) | ||
538 | { | ||
539 | struct nf_conn_help *help = nfct_help(ct); | ||
540 | struct nf_conntrack_expect *exp; | ||
541 | struct hlist_node *n, *next; | ||
542 | |||
543 | spin_lock_bh(&nf_conntrack_lock); | ||
544 | hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) { | ||
545 | if (!del_timer(&exp->timeout)) | ||
546 | continue; | ||
547 | nf_ct_unlink_expect(exp); | ||
548 | nf_ct_expect_put(exp); | ||
549 | } | ||
550 | spin_unlock_bh(&nf_conntrack_lock); | ||
551 | } | ||
552 | |||
536 | static int set_expected_rtp(struct sk_buff *skb, | 553 | static int set_expected_rtp(struct sk_buff *skb, |
537 | const char **dptr, unsigned int *datalen, | 554 | const char **dptr, unsigned int *datalen, |
538 | union nf_inet_addr *addr, __be16 port) | 555 | union nf_inet_addr *addr, __be16 port) |
@@ -606,32 +623,58 @@ static int process_invite_response(struct sk_buff *skb, | |||
606 | const char **dptr, unsigned int *datalen, | 623 | const char **dptr, unsigned int *datalen, |
607 | unsigned int cseq, unsigned int code) | 624 | unsigned int cseq, unsigned int code) |
608 | { | 625 | { |
626 | enum ip_conntrack_info ctinfo; | ||
627 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | ||
628 | |||
609 | if ((code >= 100 && code <= 199) || | 629 | if ((code >= 100 && code <= 199) || |
610 | (code >= 200 && code <= 299)) | 630 | (code >= 200 && code <= 299)) |
611 | return process_sdp(skb, dptr, datalen, cseq); | 631 | return process_sdp(skb, dptr, datalen, cseq); |
612 | 632 | else { | |
613 | return NF_ACCEPT; | 633 | flush_expectations(ct); |
634 | return NF_ACCEPT; | ||
635 | } | ||
614 | } | 636 | } |
615 | 637 | ||
616 | static int process_update_response(struct sk_buff *skb, | 638 | static int process_update_response(struct sk_buff *skb, |
617 | const char **dptr, unsigned int *datalen, | 639 | const char **dptr, unsigned int *datalen, |
618 | unsigned int cseq, unsigned int code) | 640 | unsigned int cseq, unsigned int code) |
619 | { | 641 | { |
642 | enum ip_conntrack_info ctinfo; | ||
643 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | ||
644 | |||
620 | if ((code >= 100 && code <= 199) || | 645 | if ((code >= 100 && code <= 199) || |
621 | (code >= 200 && code <= 299)) | 646 | (code >= 200 && code <= 299)) |
622 | return process_sdp(skb, dptr, datalen, cseq); | 647 | return process_sdp(skb, dptr, datalen, cseq); |
623 | 648 | else { | |
624 | return NF_ACCEPT; | 649 | flush_expectations(ct); |
650 | return NF_ACCEPT; | ||
651 | } | ||
625 | } | 652 | } |
626 | 653 | ||
627 | static int process_prack_response(struct sk_buff *skb, | 654 | static int process_prack_response(struct sk_buff *skb, |
628 | const char **dptr, unsigned int *datalen, | 655 | const char **dptr, unsigned int *datalen, |
629 | unsigned int cseq, unsigned int code) | 656 | unsigned int cseq, unsigned int code) |
630 | { | 657 | { |
658 | enum ip_conntrack_info ctinfo; | ||
659 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | ||
660 | |||
631 | if ((code >= 100 && code <= 199) || | 661 | if ((code >= 100 && code <= 199) || |
632 | (code >= 200 && code <= 299)) | 662 | (code >= 200 && code <= 299)) |
633 | return process_sdp(skb, dptr, datalen, cseq); | 663 | return process_sdp(skb, dptr, datalen, cseq); |
664 | else { | ||
665 | flush_expectations(ct); | ||
666 | return NF_ACCEPT; | ||
667 | } | ||
668 | } | ||
669 | |||
670 | static int process_bye_request(struct sk_buff *skb, | ||
671 | const char **dptr, unsigned int *datalen, | ||
672 | unsigned int cseq) | ||
673 | { | ||
674 | enum ip_conntrack_info ctinfo; | ||
675 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | ||
634 | 676 | ||
677 | flush_expectations(ct); | ||
635 | return NF_ACCEPT; | 678 | return NF_ACCEPT; |
636 | } | 679 | } |
637 | 680 | ||
@@ -640,6 +683,7 @@ static const struct sip_handler sip_handlers[] = { | |||
640 | SIP_HANDLER("UPDATE", process_sdp, process_update_response), | 683 | SIP_HANDLER("UPDATE", process_sdp, process_update_response), |
641 | SIP_HANDLER("ACK", process_sdp, NULL), | 684 | SIP_HANDLER("ACK", process_sdp, NULL), |
642 | SIP_HANDLER("PRACK", process_sdp, process_prack_response), | 685 | SIP_HANDLER("PRACK", process_sdp, process_prack_response), |
686 | SIP_HANDLER("BYE", process_bye_request, NULL), | ||
643 | }; | 687 | }; |
644 | 688 | ||
645 | static int process_sip_response(struct sk_buff *skb, | 689 | static int process_sip_response(struct sk_buff *skb, |