Merge lp:~christof-mroz/hipl/hipfw-timeout into lp:hipl

Proposed by Christof Mroz
Status: Superseded
Proposed branch: lp:~christof-mroz/hipl/hipfw-timeout
Merge into: lp:hipl
Diff against target: 693 lines (+353/-88)
11 files modified
Makefile.am (+2/-1)
firewall/conntrack.c (+86/-10)
firewall/conntrack.h (+6/-0)
firewall/firewall.c (+78/-66)
firewall/firewall_defines.h (+8/-8)
firewall/hslist.c (+18/-0)
firewall/hslist.h (+2/-0)
firewall/main.c (+25/-3)
test/check_firewall.c (+1/-0)
test/firewall/conntrack.c (+126/-0)
test/firewall/test_suites.h (+1/-0)
To merge this branch: bzr merge lp:~christof-mroz/hipl/hipfw-timeout
Reviewer Review Type Date Requested Status
Diego Biurrun Needs Fixing
Stefan Götz (community) Approve
René Hummen Pending
Review via email: mp+54339@code.launchpad.net

This proposal supersedes a proposal from 2011-03-22.

This proposal has been superseded by a proposal from 2011-03-27.

Description of the change

Addressed the review comments and added a unit test.

To post a comment you must log in.
Revision history for this message
Stefan Götz (stefan.goetz-deactivatedaccount) wrote : Posted in a previous version of this proposal

Hi Christof!

[Full quote because we forgot to CC the merge proposal on launchpad]

On 03/18/2011 01:41 PM, Christof Mroz wrote:
> On Thu, 17 Mar 2011 19:07:34 +0100
> Stefan Götz <email address hidden> wrote:
>
>>> > > +#ifdef CONFIG_HIP_DEBUG
>>> > > +// this improves our chances of finding bugs in the timeout code
>>> > > +#define DEFAULT_CONNECTION_TIMEOUT 10; // 10 seconds
>>> > > +#define DEFAULT_CLEANUP_INTERVAL 5; // 5 seconds
>>> > > +#else
>>> > > +#define DEFAULT_CONNECTION_TIMEOUT (60 * 5); // 5 minutes
>>> > > +#define DEFAULT_CLEANUP_INTERVAL (60 * 60); // 1 minute
>>> > > +#endif
>> >
>> > [M] Please use typed constants instead of preprocessor macros where
>> > possible
> Unfortunately, defining DEFAULT_{CONNECTION_TIMEOUT,CLEANUP_INTERVAL} as
> constants leads to the following complaints:
>
> firewall/conntrack.c|98| error: initializer element is not constant
> firewall/conntrack.c|109| error: initializer element is not constant

Erch, yes, one can only do that in C++, not in C. Can we move HIPL to C++, pleeeeeease? ;-)

> I could set the globals directly depending on CONFIG_HIP_DEBUG, but that
> wouldn't look so neat in my opinion, especially considering the doxygen
> comments. Do you have a better idea?

No, I think preprocessor macros are our only solution.

>> > [L] Why is gettimeofday() replaced with time()?
> gettimeofday() returns more information than needed.
>
>> > [L] it seems to me that you rely on select() to unblock frequently
>> > enough to keep up with the cleanup schedule. While that is not a
>> > particularly strict schedule, would it make sense to integrate the
>> > value in 'cleanup_interval' with the timeout set for the select()
>> > call?
> The select() timeout is currently fixed to 1 second, I guess that's enough :)
> (It has been that way before I touched the code, so I don't know the reason)

Ah, i didn't check the code that far. It's alright then.

>> > [M] The function declaration and definition have different const
>> > qualifications for the 'list' arguments. I like the 'struct slist
>> > *const list' better :-) Annyoing that the compiler doesn't catch this.
> Fixed, thanks. Can't use const here because the pointer (or rather, the local
> copy of it) is modified during execution.

Ok

Stefan

review: Approve
Revision history for this message
René Hummen (rene-hummen) wrote : Posted in a previous version of this proposal

Seems that test/firewall/conntrack.c is missing.

review: Needs Fixing
Revision history for this message
Christof Mroz (christof-mroz) wrote : Posted in a previous version of this proposal

> Seems that test/firewall/conntrack.c is missing.

You're right, sry... just added it now.

lp:~christof-mroz/hipl/hipfw-timeout updated
5783. By Christof Mroz

Removed spurious newline in usage text.

5784. By Christof Mroz

Fixed compilation of firewall tests with midauth enabled.

Revision history for this message
Stefan Götz (stefan.goetz-deactivatedaccount) wrote :
Download full text (5.8 KiB)

Hi Christof!

> === modified file 'firewall/firewall.c'
> --- firewall/firewall.c 2011-03-22 10:31:37 +0000
> +++ firewall/firewall.c 2011-03-22 12:49:26 +0000
> @@ -1669,6 +1669,80 @@
> }
>
> /**
> + * Receive and process one message from hipd.
> + *
> + * @param msg A previously allocated message buffer.
> + * @return Zero on success, non-zero on error.
> + *
> + * @note The buffer @a msg is reused between calls because it is quite
> + * large.
> + */
> +static int hip_fw_handle_hipd_message(struct hip_common *msg)

[M] style: 'struct hip_common *const msg' for const correctness - sorry, I hadn't spotted this before

I know that some of the following is not your code, but it is fairly buggy, and in nasty ways, too - maybe it's something one could address as an aside in a different branch?

> +{
> + struct sockaddr_in6 sock_addr;
> + int msg_type, len, n;
> + int is_root, access_ok;
> + socklen_t alen;
> +
> + alen = sizeof(sock_addr);
> + n = recvfrom(hip_fw_async_sock, msg, sizeof(struct hip_common),
> + MSG_PEEK, (struct sockaddr *) &sock_addr, &alen);
> + if (n < 0) {
> + HIP_ERROR("Error receiving message header from daemon.\n");
> + return -1;
> + }

[H] unrelated: One should definitely check whether 'n' is equal to 'sizeof(struct hip_common)' because 'recvfrom()' might just have read a single byte but the remaining code will happily try to parse it as a valid message.

> +
> + // making sure user messages are received from hipd
> + // resetting vars to 0 because it is a loop
> + msg_type = hip_get_msg_type(msg);
> + is_root = (ntohs(sock_addr.sin6_port) < 1024);

[H] unrelated: Holy moly - the sock_addr handling is screwed up because it is assumed that it contains an IPv6 address. That can not be assumed at all in the general case. First, one should pass a 'struct sockaddr_storage' object to 'recvfrom()'. Second, one should then check whether the returned address is in fact an IPv6 address before treating it as such.

> + if (is_root) {
> + access_ok = 1;
> + } else if (!is_root &&
> + (msg_type >= HIP_MSG_ANY_MIN &&
> + msg_type <= HIP_MSG_ANY_MAX)) {
> + access_ok = 1;
> + }
> + if (!access_ok) {
> + HIP_ERROR("The sender of the message is not trusted.\n");
> + return -1;
> + }

[L] unrelated: The whole is_root and access_ok shebang could be replaced with:

if (ntohs(sock_addr.sin6_port) >= 1024 &&
    (msg_type < HIP_MSG_ANY_MIN || msg_type > HIP_MSG_ANY_MAX)) {
    HIP_ERROR("The sender of the message is not trusted.\n");
    return -1;
}

> +
> + alen = sizeof(sock_addr);
> + len = hip_get_msg_total_len(msg);
> +
> + HIP_DEBUG("Receiving message type %d (%d bytes)\n",
> + hip_get_msg_type(msg), len);
> + n = recvfrom(hip_fw_async_sock, msg, len, 0,
> + (struct sockaddr *) &sock_addr, &alen);

[H] unrelated: 'len' must be sanity checked against the amount of memory allocated for 'msg' in order to prevent a buffer overrun, which, at this point, can be caused by grafted messages from unprivilege...

Read more...

review: Needs Fixing
lp:~christof-mroz/hipl/hipfw-timeout updated
5785. By Christof Mroz

Const-correctness fix for hip_fw_handle_hipd_message().

Revision history for this message
Christof Mroz (christof-mroz) wrote :

> > +static int hip_fw_handle_hipd_message(struct hip_common *msg)
>
> [M] style: 'struct hip_common *const msg' for const correctness - sorry, I
> hadn't spotted this before

Done, thanks.

> I know that some of the following is not your code, but it is fairly buggy,
> and in nasty ways, too - maybe it's something one could address as an
> aside in a different branch?

If so, domain sockets or fifos should be considered for access control (and, really, because they're exactly made for local IPC).

> > +
> > + // making sure user messages are received from hipd
> > + // resetting vars to 0 because it is a loop
> > + msg_type = hip_get_msg_type(msg);
> > + is_root = (ntohs(sock_addr.sin6_port) < 1024);
>
> [H] unrelated: Holy moly - the sock_addr handling is screwed up because it is
> assumed that it contains an IPv6 address. That can not be assumed at all in
> the general case. First, one should pass a 'struct sockaddr_storage' object to
> 'recvfrom()'. Second, one should then check whether the returned address is in
> fact an IPv6 address before treating it as such.

Just curious: how could this happen for an AF_INET6 datagram socket, like in this case?
hipfw maintains both an AF_INET and AF_INET6 at another place socket, for example, and I assume because either one listens only on one kind of address?

> > +/**
> > + * Find an element in the singly linked list.
> > + *
> > + * @param list The linked list.
> > + * @param data The element to find.
> > + * @return The element in the linked list, or NULL if not found.
> > + */
> > +struct slist *find_in_slist(struct slist *list, const void *const data)
>
> [M] would 'const struct slist *list' work for better const correctness?

Unfortunately, the const qualifier would propagate to the return value, which can't be const.

Revision history for this message
Stefan Götz (stefan.goetz-deactivatedaccount) wrote :

> > [H] unrelated: Holy moly - the sock_addr handling is screwed up because it
> is
> > assumed that it contains an IPv6 address. That can not be assumed at all in
> > the general case. First, one should pass a 'struct sockaddr_storage' object
> to
> > 'recvfrom()'. Second, one should then check whether the returned address is
> in
> > fact an IPv6 address before treating it as such.
>
> Just curious: how could this happen for an AF_INET6 datagram socket, like in
> this case?

Oh, well I guess they can't. I was assuming the general case of not knowing the type of the source address. Personally, I would still do this sanity check, just in case.

> > > +struct slist *find_in_slist(struct slist *list, const void *const data)
> >
> > [M] would 'const struct slist *list' work for better const correctness?
>
> Unfortunately, the const qualifier would propagate to the return value, which
> can't be const.

Ok

review: Approve
Revision history for this message
Diego Biurrun (diego-biurrun) wrote :
Download full text (3.3 KiB)

 review needs-fixing

On Tue, Mar 22, 2011 at 12:49:33PM +0000, Christof Mroz wrote:
> Christof Mroz has proposed merging lp:~christof-mroz/hipl/hipfw-timeout into lp:hipl.
>
> --- Makefile.am 2011-03-22 10:31:37 +0000
> +++ Makefile.am 2011-03-22 12:49:26 +0000
> @@ -193,10 +193,28 @@
> endif
>
>
> -test_check_firewall_SOURCES = test/check_firewall.c \
> - test/firewall/file_buffer.c \
> - test/firewall/line_parser.c \
> - test/firewall/port_bindings.c
> +test_check_firewall_SOURCES = test/check_firewall.c \
> + test/firewall/file_buffer.c \
> + test/firewall/line_parser.c \
> + test/firewall/port_bindings.c \
> + test/firewall/conntrack.c \

alphabetical order

> + firewall/cache.c \
> + firewall/dlist.c \
> + firewall/esp_prot_api.c \
> + firewall/esp_prot_config.c \
> + firewall/esp_prot_conntrack.c \
> + firewall/esp_prot_fw_msg.c \
> + firewall/firewall.c \
> + firewall/firewall_control.c \
> + firewall/helpers.c \
> + firewall/hslist.c \
> + firewall/lsi.c \
> + firewall/reinject.c \
> + firewall/rule_management.c \
> + firewall/user_ipsec_api.c \
> + firewall/user_ipsec_esp.c \
> + firewall/user_ipsec_fw_msg.c \
> + firewall/user_ipsec_sadb.c

Doh, why?

> --- firewall/firewall.c 2011-03-22 10:31:37 +0000
> +++ firewall/firewall.c 2011-03-22 12:49:26 +0000
> @@ -1669,6 +1669,80 @@
>
> + // making sure user messages are received from hipd
> + // resetting vars to 0 because it is a loop
> + msg_type = hip_get_msg_type(msg);
> + is_root = (ntohs(sock_addr.sin6_port) < 1024);

pointless parentheses

> --- firewall/main.c 2011-03-22 10:31:37 +0000
> +++ firewall/main.c 2011-03-22 12:49:26 +0000
> --- test/check_firewall.c 2011-02-18 14:39:38 +0000
> +++ test/check_firewall.c 2011-03-22 12:49:26 +0000
> @@ -34,6 +34,7 @@
> SRunner *sr = srunner_create(firewall_file_buffer());
> srunner_add_suite(sr, firewall_line_parser());
> srunner_add_suite(sr, firewall_port_bindings());
> + srunner_add_suite(sr, firewall_conntrack());

nit: alphabetical order

> --- test/firewall/conntrack.c 1970-01-01 00:00:00 +0000
> +++ test/firewall/conntrack.c 2011-03-22 12:49:26 +0000
> @@ -0,0 +1,107 @@
> +
> +static struct connection *setup_connection(void) {

Put the { on the next line.

> --- test/firewall/test_suites.h 2011-02-18 14:39:38 +0000
> +++ test/firewall/test_suites.h 2011-03-22 12:49:26 +...

Read more...

review: Needs Fixing
lp:~christof-mroz/hipl/hipfw-timeout updated
5786. By Christof Mroz

Cosmetic: Fixed brace alignment.

5787. By Christof Mroz

Cosmetic: add test suites in alphabetical order.

5788. By Christof Mroz

Cosmetic: list check_firewall sources in alphabetical order.

5789. By Christof Mroz

Cosmetic: list firewall test suites in alphabetical order, also in header file.

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On Thu, 24 Mar 2011 15:27:30 +0100, Diego Biurrun <email address hidden> wrote:

>> + firewall/cache.c \
>> + firewall/dlist.c \
>> + firewall/esp_prot_api.c \
>> + firewall/esp_prot_config.c \
>> + firewall/esp_prot_conntrack.c \
>> + firewall/esp_prot_fw_msg.c \
>> + firewall/firewall.c \
>> + firewall/firewall_control.c \
>> + firewall/helpers.c \
>> + firewall/hslist.c \
>> + firewall/lsi.c \
>> + firewall/reinject.c \
>> + firewall/rule_management.c \
>> + firewall/user_ipsec_api.c \
>> + firewall/user_ipsec_esp.c \
>> + firewall/user_ipsec_fw_msg.c \
>> + firewall/user_ipsec_sadb.c
>
> Doh, why?

Ugly, I know... I use a tiny bit of code from firewall/conntrack.c in one
test, but this triggers a whole cascade of dependencies. Do you know of a
way to tell ld to use more "fine-grained" dependencies, ignoring symbols
that aren't actually referenced? As far as I see, it's pure coincidence
that the other tests are more self-contained.

>
>> --- firewall/firewall.c 2011-03-22 10:31:37 +0000
>> +++ firewall/firewall.c 2011-03-22 12:49:26 +0000
>> @@ -1669,6 +1669,80 @@
>>
>> + // making sure user messages are received from hipd
>> + // resetting vars to 0 because it is a loop
>> + msg_type = hip_get_msg_type(msg);
>> + is_root = (ntohs(sock_addr.sin6_port) < 1024);
>
> pointless parentheses

Not fixed: Copy & Pasted that, and as Stefan pointed out it would be
better to fix this function from scratch.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :

On Thu, Mar 24, 2011 at 03:54:47PM +0100, Christof Mroz wrote:
> On Thu, 24 Mar 2011 15:27:30 +0100, Diego Biurrun <email address hidden> wrote:
>
>>> + firewall/cache.c \
>>> + firewall/dlist.c \
>>> + firewall/esp_prot_api.c \
>>> + firewall/esp_prot_config.c \
>>> + firewall/esp_prot_conntrack.c \
>>> + firewall/esp_prot_fw_msg.c \
>>> + firewall/firewall.c \
>>> + firewall/firewall_control.c \
>>> + firewall/helpers.c \
>>> + firewall/hslist.c \
>>> + firewall/lsi.c \
>>> + firewall/reinject.c \
>>> + firewall/rule_management.c \
>>> + firewall/user_ipsec_api.c \
>>> + firewall/user_ipsec_esp.c \
>>> + firewall/user_ipsec_fw_msg.c \
>>> + firewall/user_ipsec_sadb.c
>>
>> Doh, why?
>
> Ugly, I know... I use a tiny bit of code from firewall/conntrack.c in one
> test, but this triggers a whole cascade of dependencies. Do you know of a
> way to tell ld to use more "fine-grained" dependencies, ignoring symbols
> that aren't actually referenced? As far as I see, it's pure coincidence
> that the other tests are more self-contained.

What do you mean by "use a tiny bit of code"?

I don't see why you need to add any of these files at all.
Dependencies should be worked out automatically.

Diego

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On Thu, 24 Mar 2011 16:18:47 +0100, Diego Biurrun <email address hidden> wrote:

>> Ugly, I know... I use a tiny bit of code from firewall/conntrack.c in
>> one test, but this triggers a whole cascade of dependencies. Do you
>> know of a way to tell ld to use more "fine-grained" dependencies,
>> ignoring symbols that aren't actually referenced? As far as I see,
>> it's pure coincidence that the other tests are more self-contained.
>
> What do you mean by "use a tiny bit of code"?

I mean that only a fraction of the symbols exported by all those object
files is needed in the unit test.

> I don't see why you need to add any of these files at all.
> Dependencies should be worked out automatically.

Put more simply: If I remove all these other files and run "make check", I
get errors about missing symbols, and I don't know what to do about it
(other than including way more symbols than necessary into the build).
Please try and see for yourself.

What do you think of simply appending firewall_hipfw_SOURCES to the list?
Wouldn't blow up Makefile.am so much.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :

On Thu, Mar 24, 2011 at 04:33:09PM +0100, Christof Mroz wrote:
>
> What do you think of simply appending firewall_hipfw_SOURCES to the list?
> Wouldn't blow up Makefile.am so much.

This would be much cleaner.

Diego

Revision history for this message
Christof Mroz (christof-mroz) wrote :
Download full text (3.1 KiB)

On Thu, 24 Mar 2011 19:14:00 +0100, Diego Biurrun <email address hidden> wrote:

> On Thu, Mar 24, 2011 at 04:33:09PM +0100, Christof Mroz wrote:
>>
>> What do you think of simply appending firewall_hipfw_SOURCES to the
>> list?
>> Wouldn't blow up Makefile.am so much.
>
> This would be much cleaner.

The following happens to work, are you fine with that?

=== modified file 'Makefile.am'
--- Makefile.am 2011-03-24 14:37:48 +0000
+++ Makefile.am 2011-03-24 19:00:18 +0000
@@ -193,28 +193,12 @@
  endif

-test_check_firewall_SOURCES = test/check_firewall.c \
- test/firewall/conntrack.c \
- test/firewall/file_buffer.c \
- test/firewall/line_parser.c \
- test/firewall/port_bindings.c \
- firewall/cache.c \
- firewall/dlist.c \
- firewall/esp_prot_api.c \
- firewall/esp_prot_config.c \
- firewall/esp_prot_conntrack.c \
- firewall/esp_prot_fw_msg.c \
- firewall/firewall.c \
- firewall/firewall_control.c \
- firewall/helpers.c \
- firewall/hslist.c \
- firewall/lsi.c \
- firewall/reinject.c \
- firewall/rule_management.c \
- firewall/user_ipsec_api.c \
- firewall/user_ipsec_esp.c \
- firewall/user_ipsec_fw_msg.c \
- firewall/user_ipsec_sadb.c
+test_check_firewall_SOURCES = test/check_firewall.c \
+ test/firewall/conntrack.c \
+ test/firewall/file_buffer.c \
+ test/firewall/line_parser.c \
+ test/firewall/port_bindings.c \
+ $(firewall_hipfw_SOURCES)

  if HIP_MIDAUTH
  test_check_firewall_SOURCES += firewall/midauth.c \
@@ -246,6 +230,8 @@
  tools_hipconf_LDADD = lib/core/libhipcore.la
  tools_pisacert_LDADD = lib/core/libhipcore.la

+test_check_firewall_LDFLAGS = -Wl,-zmuldefs
+
  dist_sbin_SCRIPTS = tools/hipdnskeyparse/hipdnskeyparse \
                      tools/hipdnsproxy/hipdnsproxy \
                      tools/nsupdate.pl

-zmuldefs is necessary because we have multiple symbol definitions here
(which point to equivalent code though, apart from main()). This option
causes ld to prefer those objects listed first, which in turn belong to
the sources listed first.

One question though, since you know more about the build system than me:
Why are the LDFLAGS passed to gcc verbatim, i.e., why is the -Wl
necessary? Shouldn't gcc's (or make's?) ld child process pick up the
LDFLAGS instead, which would render...

Read more...

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :

On Thu, Mar 24, 2011 at 08:08:37PM +0100, Christof Mroz wrote:
> On Thu, 24 Mar 2011 19:14:00 +0100, Diego Biurrun <email address hidden> wrote:
>
>> On Thu, Mar 24, 2011 at 04:33:09PM +0100, Christof Mroz wrote:
>>>
>>> What do you think of simply appending firewall_hipfw_SOURCES to the
>>> list? Wouldn't blow up Makefile.am so much.
>>
>> This would be much cleaner.
>
> The following happens to work, are you fine with that?

I implemented something better I think. Just pull from trunk.

Diego

Revision history for this message
René Hummen (rene-hummen) wrote :

The connection tracking functionality of the hipfw can be turned off with the -F option. How do your changes cope with this fact?

Did you test that "hipfw -F" is also running as expected? Especially, the call "hip_fw_conntrack_periodic_cleanup(time(NULL));" might cause problems in this case.

lp:~christof-mroz/hipl/hipfw-timeout updated
5790. By Christof Mroz

Skip periodic cleanup if no connections are tracked anyway (-F option).

5791. By Christof Mroz

Warn about unused connection timeout.

5792. By Christof Mroz

Merged with trunk.

5793. By Christof Mroz

Remove parameter of hip_fw_periodic_cleanup(), introduced in a previous commit, again.

The parameter was introduced to decouple hip_fw_periodic_cleanup() from external state (namely: the system time).
While this leads to simpler unit tests, this method has two drawbacks:

Strict evaluation of function parameters may require more processing than necessary, outside of unit tests.
In this particular case, time(NULL) was always called regardless of whether timeouts are currently enabled. This check for necessity is embedded inside the function, and rightly so: it's not the caller's responsibility to take shortcuts.

Also, even though unit testing should promote a more modular, "stateless" train of thought, it must not incur performance hits in production builds (but rather sacrifice some comfort in the test code).

Instead, this commit solves the problem using a fake time() implementation with predictable output, allowing us to keep the original function prototype of hip_fw_periodic_cleanup().

Now we're talking about a minimum of burnt cycles here, yes. But if anything, I'd like to keep this new unit test as a proof of concept for future tests that may more heavily depend on external state...
Replaying whole packet captures, perhaps.

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On Sun, 27 Mar 2011 15:39:29 +0200, René Hummen
<email address hidden> wrote:

> The connection tracking functionality of the hipfw can be turned off
> with the -F option. How do your changes cope with this fact?
>
> Did you test that "hipfw -F" is also running as expected? Especially,
> the call "hip_fw_conntrack_periodic_cleanup(time(NULL));" might cause
> problems in this case.

No connection tracking means no connections to iterate through and time
out.
I'll add an explicit check though, for clarity and forward compatibility.

lp:~christof-mroz/hipl/hipfw-timeout updated
5794. By Christof Mroz

Don't document non-existant parameter.

5795. By Christof Mroz

Various cosmetic changes in conntrack test suite.

5796. By Christof Mroz

Merged with trunk.

5797. By Christof Mroz

Remove preprocessor macro indirection for default value.

5798. By Christof Mroz

Document return value more specifically.

5799. By Christof Mroz

Move <check.h> in front of <signal.h>.

5800. By Christof Mroz

Separate includes from code by two blank lines.

5801. By Christof Mroz

Handle clock skews gracefully rather than using an assertion.

The unit tests were updated accordingly.

5802. By Christof Mroz

Document time(2) mock function in firewall/conntrack.c test suite.

5803. By Christof Mroz

Don't rely on GNU extensions in static array initializers.

5804. By Christof Mroz

Documentation typo.

5805. By Christof Mroz

Merged trunk revision 5813.

5806. By Christof Mroz

Merged mock-functions branch and updated tests accordingly.

5807. By Christof Mroz

Merge with lp:~christof-mroz/hipl/mock-functions/ revision 5816.

5808. By Christof Mroz

Merged with mock-functions branch.

5809. By Christof Mroz

Merged trunk rev 5816.

5810. By Christof Mroz

Merged lp:~christof-mroz/hipl/mock-functions rev 5826.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2011-03-25 17:51:40 +0000
3+++ Makefile.am 2011-03-27 15:47:24 +0000
4@@ -128,7 +128,6 @@
5 endif
6
7 firewall_hipfw_sources = firewall/cache.c \
8- firewall/conntrack.c \
9 firewall/dlist.c \
10 firewall/esp_prot_api.c \
11 firewall/esp_prot_config.c \
12@@ -159,6 +158,7 @@
13 # To avoid duplicate symbols during linking some object files need to excluded.
14 # Add all files that need to be excluded here.
15 firewall_hipfw_SOURCES = $(firewall_hipfw_sources) \
16+ firewall/conntrack.c \
17 firewall/main.c
18
19 lib_core_libhipcore_la_SOURCES = lib/core/builder.c \
20@@ -198,6 +198,7 @@
21
22
23 test_check_firewall_SOURCES = test/check_firewall.c \
24+ test/firewall/conntrack.c \
25 test/firewall/file_buffer.c \
26 test/firewall/line_parser.c \
27 test/firewall/port_bindings.c \
28
29=== modified file 'firewall/conntrack.c'
30--- firewall/conntrack.c 2011-03-24 17:34:21 +0000
31+++ firewall/conntrack.c 2011-03-27 15:47:24 +0000
32@@ -74,8 +74,33 @@
33 #include "reinject.h"
34
35
36-static struct dlist *hip_list = NULL;
37-static struct dlist *esp_list = NULL;
38+static struct dlist *hip_list = NULL;
39+static struct dlist *esp_list = NULL;
40+static struct slist *conn_list = NULL;
41+
42+#define DEFAULT_CONNECTION_TIMEOUT (60 * 5); // 5 minutes
43+#define DEFAULT_CLEANUP_INTERVAL (60 * 1); // 1 minute
44+
45+/**
46+ * Interval between sweeps in hip_fw_conntrack_periodic_cleanup(),
47+ * in seconds.
48+ * Because all active connections are traversed, this should not be too
49+ * low for performance reasons.
50+ *
51+ * @see hip_fw_conntrack_periodic_cleanup()
52+ */
53+time_t cleanup_interval = DEFAULT_CLEANUP_INTERVAL;
54+
55+/**
56+ * Connection timeout in seconds, or zero to disable timeout.
57+ * This actually specifies the minimum period of inactivity before a
58+ * connection is considered stale. Thus, a connection may be inactive for
59+ * at most ::connection_timeout plus ::cleanup_interval seconds before
60+ * getting removed.
61+ *
62+ * @see hip_fw_conntrack_periodic_cleanup()
63+ */
64+time_t connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
65
66 enum {
67 STATE_NEW,
68@@ -84,9 +109,6 @@
69 STATE_CLOSING
70 };
71
72-int timeout_checking = 0;
73-unsigned long timeout_value = 0;
74-
75 /*------------print functions-------------*/
76 /**
77 * prints out the list of addresses of esp_addr_list
78@@ -434,9 +456,8 @@
79
80 connection = calloc(1, sizeof(struct connection));
81
82- connection->state = STATE_ESTABLISHED;
83- //set time stamp
84- gettimeofday(&connection->time_stamp, NULL);
85+ connection->state = STATE_ESTABLISHED;
86+ connection->timestamp = time(NULL);
87 #ifdef HIP_CONFIG_MIDAUTH
88 connection->pisa_state = PISA_STATE_DISALLOW;
89 #endif
90@@ -467,6 +488,7 @@
91 hip_list = append_to_list(hip_list, connection->original.hip_tuple);
92 hip_list = append_to_list(hip_list, connection->reply.hip_tuple);
93 HIP_DEBUG("inserting connection \n");
94+ conn_list = append_to_slist(conn_list, connection);
95 }
96
97 /**
98@@ -597,6 +619,8 @@
99 */
100 static void remove_connection(struct connection *connection)
101 {
102+ struct slist *conn_link;
103+
104 HIP_DEBUG("remove_connection: tuple list before: \n");
105 print_tuple_list();
106
107@@ -604,6 +628,10 @@
108 print_esp_list();
109
110 if (connection) {
111+ HIP_ASSERT(conn_link = find_in_slist(conn_list, connection));
112+ conn_list = remove_link_slist(conn_list, conn_link);
113+ free(conn_link);
114+
115 remove_tuple(&connection->original);
116 remove_tuple(&connection->reply);
117
118@@ -1653,7 +1681,7 @@
119 // update time_stamp only on valid packets
120 // for new connections time_stamp is set when creating
121 if (tuple->connection) {
122- gettimeofday(&tuple->connection->time_stamp, NULL);
123+ tuple->connection->timestamp = time(NULL);
124 } else {
125 HIP_DEBUG("Tuple connection NULL, could not timestamp\n");
126 }
127@@ -1816,7 +1844,7 @@
128 out_err:
129 // if we are going to accept the packet, update time stamp of the connection
130 if (err > 0) {
131- gettimeofday(&tuple->connection->time_stamp, NULL);
132+ tuple->connection->timestamp = time(NULL);
133 }
134
135 HIP_DEBUG("verdict %d \n", err);
136@@ -1957,3 +1985,51 @@
137 HIP_DEBUG("get_tuple_by_hits: no connection found\n");
138 return NULL;
139 }
140+
141+/**
142+ * Do some necessary bookkeeping concerning connection tracking.
143+ * Currently, this only makes sure that stale locations will be removed.
144+ * The actual tasks will be run at most once per ::connection_timeout
145+ * seconds, no matter how often you call the function.
146+ *
147+ * @param now The current time.
148+ *
149+ * @note Don't call this from a thread or timer, since most of hipfw is not
150+ * reentrant (and so this function isn't either).
151+ */
152+void hip_fw_conntrack_periodic_cleanup(void)
153+{
154+ static time_t last_check = 0; // timestamp of last call
155+ struct slist *iter_conn;
156+ struct connection *conn;
157+
158+ if (connection_timeout == 0 || !filter_traffic) {
159+ // timeout disabled, or no connections
160+ // tracked in the first place
161+ return;
162+ }
163+
164+ const time_t now = time(NULL);
165+
166+ HIP_ASSERT(now >= last_check);
167+ if (now - last_check >= cleanup_interval) {
168+ HIP_DEBUG("Checking for connection timeouts\n");
169+
170+ iter_conn = conn_list;
171+ while (iter_conn) {
172+ conn = iter_conn->data;
173+ iter_conn = iter_conn->next; // iter_conn might get removed
174+
175+ HIP_ASSERT(now >= conn->timestamp);
176+ if (now - conn->timestamp >= connection_timeout) {
177+ HIP_DEBUG("Connection timed out:\n");
178+ HIP_DEBUG_HIT("src HIT", &conn->original.hip_tuple->data->src_hit);
179+ HIP_DEBUG_HIT("dst HIT", &conn->original.hip_tuple->data->dst_hit);
180+
181+ remove_connection(conn);
182+ }
183+ }
184+
185+ last_check = now;
186+ }
187+}
188
189=== modified file 'firewall/conntrack.h'
190--- firewall/conntrack.h 2011-01-04 14:10:46 +0000
191+++ firewall/conntrack.h 2011-03-27 15:47:24 +0000
192@@ -38,6 +38,10 @@
193
194
195 /*-------------- CONNECTION TRACKING ------------*/
196+
197+extern time_t connection_timeout;
198+extern time_t cleanup_interval;
199+
200 enum {
201 ORIGINAL_DIR,
202 REPLY_DIR,
203@@ -59,4 +63,6 @@
204 const struct in6_addr *dst_hit);
205 int hipfw_relay_esp(const struct hip_fw_context *ctx);
206
207+void hip_fw_conntrack_periodic_cleanup(void);
208+
209 #endif /* HIP_FIREWALL_CONNTRACK_H */
210
211=== modified file 'firewall/firewall.c'
212--- firewall/firewall.c 2011-03-24 11:35:48 +0000
213+++ firewall/firewall.c 2011-03-27 15:47:24 +0000
214@@ -1668,6 +1668,80 @@
215 }
216
217 /**
218+ * Receive and process one message from hipd.
219+ *
220+ * @param msg A previously allocated message buffer.
221+ * @return Zero on success, non-zero on error.
222+ *
223+ * @note The buffer @a msg is reused between calls because it is quite
224+ * large.
225+ */
226+static int hip_fw_handle_hipd_message(struct hip_common *const msg)
227+{
228+ struct sockaddr_in6 sock_addr;
229+ int msg_type, len, n;
230+ int is_root, access_ok;
231+ socklen_t alen;
232+
233+ alen = sizeof(sock_addr);
234+ n = recvfrom(hip_fw_async_sock, msg, sizeof(struct hip_common),
235+ MSG_PEEK, (struct sockaddr *) &sock_addr, &alen);
236+ if (n < 0) {
237+ HIP_ERROR("Error receiving message header from daemon.\n");
238+ return -1;
239+ }
240+
241+ // making sure user messages are received from hipd
242+ // resetting vars to 0 because it is a loop
243+ msg_type = hip_get_msg_type(msg);
244+ is_root = (ntohs(sock_addr.sin6_port) < 1024);
245+ if (is_root) {
246+ access_ok = 1;
247+ } else if (!is_root &&
248+ (msg_type >= HIP_MSG_ANY_MIN &&
249+ msg_type <= HIP_MSG_ANY_MAX)) {
250+ access_ok = 1;
251+ }
252+ if (!access_ok) {
253+ HIP_ERROR("The sender of the message is not trusted.\n");
254+ return -1;
255+ }
256+
257+ alen = sizeof(sock_addr);
258+ len = hip_get_msg_total_len(msg);
259+
260+ HIP_DEBUG("Receiving message type %d (%d bytes)\n",
261+ hip_get_msg_type(msg), len);
262+ n = recvfrom(hip_fw_async_sock, msg, len, 0,
263+ (struct sockaddr *) &sock_addr, &alen);
264+
265+ if (n < 0) {
266+ HIP_ERROR("Error receiving message parameters from daemon.\n");
267+ return -1;
268+ }
269+
270+ HIP_ASSERT(n == len);
271+
272+ if (ntohs(sock_addr.sin6_port) != HIP_DAEMON_LOCAL_PORT) {
273+ int type = hip_get_msg_type(msg);
274+ if (type == HIP_MSG_FW_BEX_DONE) {
275+ HIP_DEBUG("HIP_MSG_FW_BEX_DONE\n");
276+ HIP_DEBUG("%d == %d\n", ntohs(sock_addr.sin6_port),
277+ HIP_DAEMON_LOCAL_PORT);
278+ }
279+ HIP_DEBUG("Drop, message not from hipd\n");
280+ return -1;
281+ }
282+
283+ if (hip_handle_msg(msg) < 0) {
284+ HIP_ERROR("Error handling message\n");
285+ return -1;
286+ }
287+
288+ return 0;
289+}
290+
291+/**
292 * Hipfw should be started before hipd to make sure
293 * that nobody can bypass ACLs. However, some hipfw
294 * extensions (e.g. userspace ipsec) work consistently
295@@ -1723,17 +1797,14 @@
296 const bool kill_old,
297 const bool limit_capabilities)
298 {
299- int err = 0, highest_descriptor, i;
300- int n, len;
301+ int err = 0, highest_descriptor, i;
302 struct ipq_handle *h4 = NULL, *h6 = NULL;
303 struct hip_common *msg = NULL;
304 struct sockaddr_in6 sock_addr = { 0 };
305- socklen_t alen;
306 fd_set read_fdset;
307 struct timeval timeout;
308 unsigned char buf[HIP_MAX_PACKET];
309 struct hip_fw_context ctx;
310- int is_root = 0, access_ok = 0, msg_type = 0; //variables for accepting user messages only from hipd
311
312 #ifdef CONFIG_HIP_PERFORMANCE
313 HIP_DEBUG("Creating perf set\n");
314@@ -1888,69 +1959,10 @@
315
316 if (FD_ISSET(hip_fw_async_sock, &read_fdset)) {
317 HIP_DEBUG("****** Received HIPD message ******\n");
318- memset(&sock_addr, 0, sizeof(sock_addr));
319- alen = sizeof(sock_addr);
320- n = recvfrom(hip_fw_async_sock, msg, sizeof(struct hip_common),
321- MSG_PEEK, (struct sockaddr *) &sock_addr, &alen);
322- if (n < 0) {
323- HIP_ERROR("Error receiving message header from daemon.\n");
324- err = -1;
325- continue;
326- }
327-
328-
329- /*making sure user messages are received from hipd*/
330- //resetting vars to 0 because it is a loop
331- is_root = 0, access_ok = 0, msg_type = 0;
332- msg_type = hip_get_msg_type(msg);
333- is_root = (ntohs(sock_addr.sin6_port) < 1024);
334- if (is_root) {
335- access_ok = 1;
336- } else if (!is_root &&
337- (msg_type >= HIP_MSG_ANY_MIN &&
338- msg_type <= HIP_MSG_ANY_MAX)) {
339- access_ok = 1;
340- }
341- if (!access_ok) {
342- HIP_ERROR("The sender of the message is not trusted.\n");
343- err = -1;
344- continue;
345- }
346-
347- alen = sizeof(sock_addr);
348- len = hip_get_msg_total_len(msg);
349-
350- HIP_DEBUG("Receiving message type %d (%d bytes)\n",
351- hip_get_msg_type(msg), len);
352- n = recvfrom(hip_fw_async_sock, msg, len, 0,
353- (struct sockaddr *) &sock_addr, &alen);
354-
355- if (n < 0) {
356- HIP_ERROR("Error receiving message parameters from daemon.\n");
357- err = -1;
358- continue;
359- }
360-
361- HIP_ASSERT(n == len);
362-
363- if (ntohs(sock_addr.sin6_port) != HIP_DAEMON_LOCAL_PORT) {
364- int type = hip_get_msg_type(msg);
365- if (type == HIP_MSG_FW_BEX_DONE) {
366- HIP_DEBUG("HIP_MSG_FW_BEX_DONE\n");
367- HIP_DEBUG("%d == %d\n", ntohs(sock_addr.sin6_port),
368- HIP_DAEMON_LOCAL_PORT);
369- }
370- HIP_DEBUG("Drop, message not from hipd\n");
371- err = -1;
372- continue;
373- }
374-
375- err = hip_handle_msg(msg);
376- if (err < 0) {
377- HIP_ERROR("Error handling message\n");
378- continue;
379- }
380+ err = hip_fw_handle_hipd_message(msg);
381 }
382+
383+ hip_fw_conntrack_periodic_cleanup();
384 }
385
386 out_err:
387
388=== modified file 'firewall/firewall_defines.h'
389--- firewall/firewall_defines.h 2011-01-11 13:59:46 +0000
390+++ firewall/firewall_defines.h 2011-03-27 15:47:24 +0000
391@@ -136,16 +136,16 @@
392 };
393
394 struct connection {
395- struct tuple original;
396- struct tuple reply;
397- int verify_responder;
398- int state;
399- struct timeval time_stamp;
400+ struct tuple original;
401+ struct tuple reply;
402+ int verify_responder;
403+ int state;
404+ time_t timestamp;
405 /* members needed for ESP protection extension */
406- int num_esp_prot_tfms;
407- uint8_t esp_prot_tfms[MAX_NUM_TRANSFORMS];
408+ int num_esp_prot_tfms;
409+ uint8_t esp_prot_tfms[MAX_NUM_TRANSFORMS];
410 #ifdef CONFIG_HIP_MIDAUTH
411- int pisa_state;
412+ int pisa_state;
413 #endif
414 };
415
416
417=== modified file 'firewall/hslist.c'
418--- firewall/hslist.c 2010-12-13 19:09:27 +0000
419+++ firewall/hslist.c 2011-03-27 15:47:24 +0000
420@@ -129,3 +129,21 @@
421
422 return list;
423 }
424+
425+/**
426+ * Find an element in the singly linked list.
427+ *
428+ * @param list The linked list.
429+ * @param data The element to find.
430+ * @return The element in the linked list, or NULL if not found.
431+ */
432+struct slist *find_in_slist(struct slist *list, const void *const data)
433+{
434+ while (list) {
435+ if (list->data == data) {
436+ return list;
437+ }
438+ list = list->next;
439+ }
440+ return NULL;
441+}
442
443=== modified file 'firewall/hslist.h'
444--- firewall/hslist.h 2010-12-13 19:09:27 +0000
445+++ firewall/hslist.h 2011-03-27 15:47:24 +0000
446@@ -32,4 +32,6 @@
447
448 struct slist *remove_link_slist(struct slist *list, struct slist *link);
449
450+struct slist *find_in_slist(struct slist *list, const void *const data);
451+
452 #endif /* HIP_FIREWALL_HSLIST_H */
453
454=== modified file 'firewall/main.c'
455--- firewall/main.c 2011-03-22 10:31:37 +0000
456+++ firewall/main.c 2011-03-27 15:47:24 +0000
457@@ -33,6 +33,8 @@
458 * Anything defined here will be unavailable in these cases.
459 */
460
461+#define _BSD_SOURCE
462+
463 #include <stdio.h>
464 #include <stdlib.h>
465 #include <unistd.h>
466@@ -42,6 +44,7 @@
467 #include "lib/core/debug.h"
468 #include "lib/core/util.h"
469 #include "firewall.h"
470+#include "conntrack.h"
471
472
473 /**
474@@ -50,7 +53,7 @@
475 static void hipfw_usage(void)
476 {
477 puts("HIP Firewall");
478- puts("Usage: hipfw [-f file_name] [-d|-v] [-A] [-F] [-H] [-b] [-a] [-c] [-k] [-i|-I|-e] [-l] [-o] [-p] [-h] [-V]");
479+ puts("Usage: hipfw [-f file_name] [-d|-v] [-A] [-F] [-H] [-b] [-a] [-c] [-k] [-i|-I|-e] [-l] [-o] [-p] [-t <seconds>] [-h] [-V]");
480 #ifdef CONFIG_HIP_MIDAUTH
481 puts(" [-m]");
482 #endif
483@@ -69,6 +72,7 @@
484 puts(" -e = use esp protection extension (also sets -i)");
485 puts(" -l = activate lsi support");
486 puts(" -p = run with lowered privileges. iptables rules will not be flushed on exit");
487+ puts(" -t <seconds> = set timeout interval to <seconds>. Disable if <seconds> = 0");
488 puts(" -h = print this help");
489 #ifdef CONFIG_HIP_MIDAUTH
490 puts(" -m = middlebox authentication");
491@@ -97,13 +101,14 @@
492 bool limit_capabilities = false;
493 const char *rule_file = NULL;
494
495- int ch;
496+ char *end_of_number;
497+ int ch;
498
499 /* Make sure that root path is set up correctly (e.g. on Fedora 9).
500 * Otherwise may get warnings from system_print() commands. */
501 setenv("PATH", HIP_DEFAULT_EXEC_PATH, 1);
502
503- while ((ch = getopt(argc, argv, "aAbcdef:FhHiIklmpvV")) != -1) {
504+ while ((ch = getopt(argc, argv, "aAbcdef:FhHiIklmpt:vV")) != -1) {
505 switch (ch) {
506 case 'A':
507 accept_hip_esp_traffic_by_default = 1;
508@@ -154,6 +159,18 @@
509 case 'p':
510 limit_capabilities = 1;
511 break;
512+ case 't':
513+ connection_timeout = strtoul(optarg, &end_of_number, 10);
514+ if (end_of_number == optarg) {
515+ fprintf(stderr, "Error: Invalid timeout given\n");
516+ hipfw_usage();
517+ return EXIT_FAILURE;
518+ }
519+ if (connection_timeout < cleanup_interval) {
520+ /* we must poll at least once per timeout interval */
521+ cleanup_interval = connection_timeout;
522+ }
523+ break;
524 case 'v':
525 log_level = LOGDEBUG_MEDIUM;
526 hip_set_logfmt(LOGFMT_SHORT);
527@@ -172,6 +189,11 @@
528 }
529 }
530
531+ if (connection_timeout > 0 && !filter_traffic) {
532+ puts("Warning: timeouts (-t) have no effect with connection");
533+ puts(" tracking disabled (-F)");
534+ }
535+
536 if (geteuid() != 0) {
537 HIP_ERROR("Firewall must be run as root\n");
538 exit(-1);
539
540=== modified file 'test/check_firewall.c'
541--- test/check_firewall.c 2011-02-18 14:39:38 +0000
542+++ test/check_firewall.c 2011-03-27 15:47:24 +0000
543@@ -32,6 +32,7 @@
544 {
545 int number_failed;
546 SRunner *sr = srunner_create(firewall_file_buffer());
547+ srunner_add_suite(sr, firewall_conntrack());
548 srunner_add_suite(sr, firewall_line_parser());
549 srunner_add_suite(sr, firewall_port_bindings());
550
551
552=== added file 'test/firewall/conntrack.c'
553--- test/firewall/conntrack.c 1970-01-01 00:00:00 +0000
554+++ test/firewall/conntrack.c 2011-03-27 15:47:24 +0000
555@@ -0,0 +1,126 @@
556+/*
557+ * Copyright (c) 2010 Aalto University and RWTH Aachen University.
558+ *
559+ * Permission is hereby granted, free of charge, to any person
560+ * obtaining a copy of this software and associated documentation
561+ * files (the "Software"), to deal in the Software without
562+ * restriction, including without limitation the rights to use,
563+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
564+ * copies of the Software, and to permit persons to whom the
565+ * Software is furnished to do so, subject to the following
566+ * conditions:
567+ *
568+ * The above copyright notice and this permission notice shall be
569+ * included in all copies or substantial portions of the Software.
570+ *
571+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
572+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
573+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
574+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
575+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
576+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
577+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
578+ * OTHER DEALINGS IN THE SOFTWARE.
579+ */
580+
581+#define _BSD_SOURCE
582+
583+#include <check.h>
584+
585+#include <net/if.h>
586+#include <arpa/inet.h>
587+#include <netinet/in.h>
588+#include <netinet/ip.h>
589+#include <signal.h>
590+#include <time.h>
591+
592+#include "firewall/conntrack.h"
593+#include "firewall/conntrack.c"
594+#include "test_suites.h"
595+
596+static time_t fake_time = 0;
597+
598+time_t time(time_t *t) {
599+ if (t) {
600+ *t = fake_time;
601+ }
602+
603+ return fake_time;
604+}
605+
606+static struct connection *setup_connection(void)
607+{
608+ struct hip_data data = { };
609+
610+ inet_pton(AF_INET6, "2001:12:bd2d:d23e:4a09:b2ab:6414:e110", &data.src_hit);
611+ inet_pton(AF_INET6, "2001:10:f039:6bc5:cab3:0727:7fbc:9dcb", &data.dst_hit);
612+
613+ insert_new_connection(&data);
614+
615+ fail_if(conn_list == NULL, "No connection inserted.");
616+ fail_if(conn_list->next != NULL, "More than one connection inserted.");
617+ fail_if(conn_list->data == NULL, "No connection allocated.");
618+ return conn_list->data;
619+}
620+
621+START_TEST(test_hip_fw_conntrack_periodic_cleanup_timeout)
622+{
623+ struct connection *conn;
624+
625+ cleanup_interval = 0;
626+ connection_timeout = 2;
627+
628+ conn = setup_connection();
629+ conn->timestamp = 1;
630+
631+ fake_time = 2;
632+ hip_fw_conntrack_periodic_cleanup(); // don't time out yet
633+ fail_if(conn_list == NULL, "Connection was removed too early.");
634+
635+ fake_time = 3;
636+ hip_fw_conntrack_periodic_cleanup(); // time out this time
637+ fail_unless(conn_list == NULL, "Idle connection was not removed.");
638+}
639+END_TEST
640+
641+START_TEST(test_hip_fw_conntrack_periodic_cleanup_glitched_system_time)
642+{
643+ cleanup_interval = 0;
644+
645+ fake_time = 2;
646+ hip_fw_conntrack_periodic_cleanup(); // OK
647+
648+ fake_time = 1;
649+ hip_fw_conntrack_periodic_cleanup(); // throws assertion
650+}
651+END_TEST
652+
653+START_TEST(test_hip_fw_conntrack_periodic_cleanup_glitched_packet_time)
654+{
655+ struct connection *conn;
656+
657+ cleanup_interval = 0;
658+ connection_timeout = 2;
659+
660+ fake_time = 1;
661+
662+ conn = setup_connection();
663+ conn->timestamp = 1;
664+ hip_fw_conntrack_periodic_cleanup(); // OK
665+ conn->timestamp = 2;
666+ hip_fw_conntrack_periodic_cleanup(); // throws assertion
667+}
668+END_TEST
669+
670+Suite *firewall_conntrack(void)
671+{
672+ Suite *s = suite_create("firewall/conntrack");
673+
674+ TCase *tc_conntrack = tcase_create("Conntrack");
675+ tcase_add_test(tc_conntrack, test_hip_fw_conntrack_periodic_cleanup_timeout);
676+ tcase_add_exit_test(tc_conntrack, test_hip_fw_conntrack_periodic_cleanup_glitched_system_time, 1);
677+ tcase_add_exit_test(tc_conntrack, test_hip_fw_conntrack_periodic_cleanup_glitched_packet_time, 1);
678+ suite_add_tcase(s, tc_conntrack);
679+
680+ return s;
681+}
682
683=== modified file 'test/firewall/test_suites.h'
684--- test/firewall/test_suites.h 2011-02-18 14:39:38 +0000
685+++ test/firewall/test_suites.h 2011-03-27 15:47:24 +0000
686@@ -28,6 +28,7 @@
687
688 #include <check.h>
689
690+Suite *firewall_conntrack(void);
691 Suite *firewall_file_buffer(void);
692 Suite *firewall_line_parser(void);
693 Suite *firewall_port_bindings(void);

Subscribers

People subscribed via source and target branches

to all changes: