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: 688 lines (+348/-88)
11 files modified
Makefile.am (+2/-1)
firewall/conntrack.c (+81/-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
René Hummen Pending
Stefan Götz Pending
Review via email: mp+55006@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. Pay special attention to the commit message of r5793:
http://bazaar.launchpad.net/~christof-mroz/hipl/hipfw-timeout/revision/5793

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.

Revision history for this message
Stefan Götz (stefan.goetz-deactivatedaccount) wrote : Posted in a previous version of this proposal
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
Revision history for this message
Christof Mroz (christof-mroz) wrote : Posted in a previous version of this proposal

> > +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 : Posted in a previous version of this proposal

> > [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 : Posted in a previous version of this proposal
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
Revision history for this message
Christof Mroz (christof-mroz) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal
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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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.

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

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.

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

 review needs-fixing

On Sun, Mar 27, 2011 at 03:51:36PM +0000, Christof Mroz wrote:
> Christof Mroz has proposed merging lp:~christof-mroz/hipl/hipfw-timeout into lp:hipl.
>
> --- firewall/conntrack.c 2011-03-24 17:34:21 +0000
> +++ firewall/conntrack.c 2011-03-27 15:51:27 +0000
> @@ -74,8 +74,33 @@
> +
> +#define DEFAULT_CONNECTION_TIMEOUT (60 * 5); // 5 minutes
> +#define DEFAULT_CLEANUP_INTERVAL (60 * 1); // 1 minute
> +
> +time_t cleanup_interval = DEFAULT_CLEANUP_INTERVAL;
> +
> +time_t connection_timeout = DEFAULT_CONNECTION_TIMEOUT;

The defines seem completely redundant to me, just assign the values to
the variables without indirection.

> --- firewall/firewall.c 2011-03-24 11:35:48 +0000
> +++ firewall/firewall.c 2011-03-27 15:51:27 +0000
> @@ -1668,6 +1668,80 @@
>
> /**
> + * Receive and process one message from hipd.
> + *
> + * @param msg A previously allocated message buffer.
> + * @return Zero on success, non-zero on error.

You return -1, not non-zero, please say so. Positive numbers are
non-zero as well, so this is confusing.

> +static int hip_fw_handle_hipd_message(struct hip_common *const msg)
> +{
> + 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;
> + }
> +
> + // 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);

Please remove the pointless parentheses around the right-hand-side
expression.

> + 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;
> + }

You assign 1 in both branches, this seems suspicious.
The !is_root check is redundant.

> @@ -1888,69 +1959,10 @@
>
> - /*making sure user messages are received from hipd*/
> - //resetting vars to 0 because it is a loop
> - is_root = 0, access_ok = 0, msg_type = 0;
> - msg_type = hip_get_msg_type(msg);
> - is_root = (ntohs(sock_addr.sin6_port) < 1024);
> - 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;
> - }

OMG, now I see where this comes from...

I removed all extra parentheses around complete expressions in HIPL.
Not sure how to handle the rest of this code that you copypasted.
Fixing it may be out of the scope of this branch, but it sure is not
pretty...

> --- test/firewall/conntrack.c 1970-01-01 00:00:00 +0000
> +++ test/firewall/conntrack.c 2011-03-27 15:51:27 +0000
> @@ -0,0 +1,126 @@
> ...

Read more...

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

On Sun, 27 Mar 2011 19:36:27 +0200, Diego Biurrun <email address hidden> wrote:

> review needs-fixing
>
> On Sun, Mar 27, 2011 at 03:51:36PM +0000, Christof Mroz wrote:
>> Christof Mroz has proposed merging lp:~christof-mroz/hipl/hipfw-timeout
>> into lp:hipl.
>>
>> --- firewall/conntrack.c 2011-03-24 17:34:21 +0000
>> +++ firewall/conntrack.c 2011-03-27 15:51:27 +0000
>> @@ -74,8 +74,33 @@
>> +
>> +#define DEFAULT_CONNECTION_TIMEOUT (60 * 5); // 5 minutes
>> +#define DEFAULT_CLEANUP_INTERVAL (60 * 1); // 1 minute
>> +
>> +time_t cleanup_interval = DEFAULT_CLEANUP_INTERVAL;
>> +
>> +time_t connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
>
> The defines seem completely redundant to me, just assign the values to
> the variables without indirection.

I just realized that only a fraction of HIPL does it that way, but it's
not consistent... so given the choice now, I'll drop that indirection.

> Not sure how to handle the rest of this code that you copypasted.
> Fixing it may be out of the scope of this branch, but it sure is not
> pretty...

If the hipfw <-> hipd link is supposed to be purely local, this part
should be rewritten using Domain sockets or FIFOs and proper access
control (also in hipd, of course). Would be nice if someone with more
authority could either decline this idea or file a feature request (or bug
report even?) as a reminder.

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

Subscribers

People subscribed via source and target branches

to all changes: