Merge lp:~hipl-core/hipl/libhip into lp:hipl

Proposed by Xin
Status: Rejected
Rejected by: Xin
Proposed branch: lp:~hipl-core/hipl/libhip
Merge into: lp:hipl
Diff against target: 3091 lines (+2450/-114)
27 files modified
Makefile.am (+55/-46)
doc/HOWTO.xml.in (+106/-0)
hipd/main.c (+3/-4)
hipfw/hipfw.c (+1/-1)
lib/core/hostid.c (+12/-4)
lib/hipl/hadb.c (+16/-1)
lib/hipl/hidb.c (+9/-7)
lib/hipl/hipd.h (+5/-0)
lib/hipl/init.c (+297/-0)
lib/hipl/init.h (+5/-1)
lib/hipl/input.c (+5/-0)
lib/hipl/lhipl.c (+536/-0)
lib/hipl/lhipl.h (+76/-0)
lib/hipl/lhipl_operations.c (+771/-0)
lib/hipl/lhipl_operations.h (+55/-0)
lib/hipl/lhipl_sock.c (+150/-0)
lib/hipl/lhipl_sock.h (+67/-0)
lib/hipl/output.c (+33/-18)
modules/cert/hipd/cert.c (+2/-2)
modules/heartbeat/hipd/heartbeat.c (+9/-9)
modules/heartbeat_update/hipd/hb_update.c (+3/-3)
modules/midauth/hipd/midauth.c (+2/-2)
modules/update/hipd/update.c (+11/-11)
modules/update/hipd/update_builder.c (+2/-2)
modules/update/hipd/update_locator.c (+2/-2)
test/check_libhipl.c (+216/-0)
test/hipd/lsidb.c (+1/-1)
To merge this branch: bzr merge lp:~hipl-core/hipl/libhip
Reviewer Review Type Date Requested Status
Diego Biurrun Needs Fixing
René Hummen Disapprove
Christof Mroz Needs Information
Stefan Götz Pending
Review via email: mp+97589@code.launchpad.net

This proposal supersedes a proposal from 2012-02-20.

Description of the change

Mar 15, 2012 Fixed issues based on Christof and Stefan's review.

Feb 20, 2012 Code revisd based on Diego's second review and Christof's review
New APIs also have been changed to start with 'hipl_' prefix

Feb 10, 2012 code revised based on Diego's review

=============================================

Libhip merge proposal:

The libhip branch mainly aims to provide a convenient way for system test of HIPL without full installation and configuration. In addition to this purpose, it also provides a socket API alike library approach for application to use HIP. Last by not least, since vanilla Linux TCP does not yet support long periods of disconnectivity [1] , libhip can be a solution in this condition.

In the libhip branch, we build a library version of HIP for upper applications, which only exposes traditional socket like API. when using the libhip, hip control messages are transmitted over TCP or UDP, which is similar to TLS/DTLS but we have a unified protocol to handle both datagram and streaming traffic[2]. Compared to TLS/DTLS, this is a big advantage and it may be better use case for HIP[3].

In the libhip, most of code of hipd has been moved to lib/hipdaemon which then becomes a library for both hipd and libhip. By this way, the libhip can reuse the code of hipd to the max extend. This is also the reason why libhip can be a system test approach for hipd, especially in the process of base exchange, the libhip and hipd share the same code base. Meanwhile, the hip daemon, and other functionalities previous exist in the trunk, are kept unchanged and functioning after this merge.

We also implement a sample application called hipnetcat, which is a client-server style application on top of libhip and these 2 sides establish HIP association via BEX before actual data communication. The hipnetcat is integrated into our automatically test framework (check_hipnetcat). In check_hipnetcat, 2 hipnetcat processes try to establish BEX on loopback address on top of TCP/UDP, therefore, the execution of this test suite will check the functionality of base exchange in a system level.

Currently the libhip is still at an eary stage, there are several features waiting for implementation. First there is no support in the firewall; Second, although the control plane base exchange functions well, the data plane security is not implemented yet. We plan to introduce libsrtp for this purpose; Third, the libhip is not thread save yet, because the socket descriptors we use now are global variables; Last, the support of long period disconnectivity we mention in the first paragraph is not included in this merge, there will be another merge request for this feature.

[1] Schutz et al,. Protocol enhancements for intermittently connected hosts, 2005
[2] Komu et al, Technical report: Sockets and Beyond Assessing the Source Code of Network Applications, 2012
[3] Levä et al, Adoption of General-purpose Communication Protocols: the Case of Host Identity Protocol, unpublished manuscript, 2012

To post a comment you must log in.
Revision history for this message
Christof Mroz (christof-mroz) wrote : Posted in a previous version of this proposal
Download full text (3.7 KiB)

> === modified file 'lib/core/hostid.c'
> --- lib/core/hostid.c 2011-11-10 10:35:47 +0000
> +++ lib/core/hostid.c 2012-02-20 08:33:22 +0000
> @@ -743,11 +744,17 @@
> goto out_err;
> }
> } else if (!use_default) {
> + char hi_file_dup[strlen(hi_file) + 1];
> + strcpy(hi_file_dup, hi_file);
> + if ((err = check_and_create_dir(dirname(hi_file_dup), HIP_DIR_MODE))) {
> + HIP_ERROR("Could not create direcory for path: %s\n", hi_file);
> + goto out_err;
> + }

I investigated a bit and seems like PATH_MAX is 4096 chars on linux, which is probably OK even for stacks on embedded devices, but strdup() would be safer nevertheless.
My apologies for advising you to use the stack for that in the last mail (see also further below).

Probably unrelated: should this handle recursive mkdir()? check_and_create_dir() currently does not, as far as I see.

> === modified file 'lib/core/linkedlist.c'
> --- lib/core/linkedlist.c 2011-08-15 14:11:56 +0000
> +++ lib/core/linkedlist.c 2012-02-20 08:33:22 +0000
> @@ -298,6 +298,51 @@
> /**
> + * Deletes the first node from list which has the same ptr given.
> + * If there is no match, does nothing.
> + *
> + * @param linkedlist list to remoe an element from
> + * @param ptr pointer by which to identify the node
> + * @param free_element a function pointer to a function for freeing the memory
> + * allocated for an element at a node or NULL if the element
> + * itself is not to be freed.
> + */
> +void hip_ll_del_by_ptr(struct hip_ll *linkedlist, void *ptr,
> + free_elem_fn free_element)
> +{
> + struct hip_ll_node *curr;
> + struct hip_ll_node *tmp;
> +
> + /* match first list node */
> + if (linkedlist != NULL && linkedlist->element_count > 0
> + && linkedlist->head->ptr == ptr) {
> + tmp = linkedlist->head;
> + linkedlist->head = tmp->next;
> + linkedlist->element_count--;
> + if (free_element != NULL) {
> + free_element(tmp->ptr);
> + }
> + free(tmp);
> + return;
> + }
> +
> + /* match the rest list */
> + tmp = linkedlist->head;
> + for (curr = tmp->next; curr != NULL; curr = curr->next) {
> + if (curr->ptr == ptr) {
> + tmp->next = curr->next;
> + linkedlist->element_count--;
> + if (free_element != NULL) {
> + free_element(curr->ptr);
> + }
> + free(curr);
> + return;
> + }
> + tmp = tmp->next;
> + }
> +}

Looks like both loops can be merged, at first glance (untested):

if(!linkedlist || linkedlist->element_count == 0) {
 return;
}

struct hip_ll_node **storage = &linkedlist->head;
struct hip_ll_node *node = linkedlist->head;

while(node) {
 if(node->ptr == ptr) {
  *storage = node->next;
  free(node);
  node = *storage;

  linkedlist->elementcount -= 1;
  // could return here for micro optimization
 } else {
  storage = &node->next;
  node = node->next;
 }
}

> === renamed file 'hipd/init.c' => 'lib/hipdaemon/init....

Read more...

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

On 20.02.2012 21:03, Christof Mroz wrote:
> struct hip_ll_node **storage = &linkedlist->head;
> struct hip_ll_node *node = linkedlist->head;
>
> while(node) {
> if(node->ptr == ptr) {
> *storage = node->next;
> free(node);
> node = *storage;
>
> linkedlist->elementcount -= 1;
> // could return here for micro optimization
> } else {
> storage = &node->next;
> node = node->next;
> }
> }

Just realized this can be compacted some more:

struct hip_ll_node **storage = &linkedlist->head;

while(*storage) {
     struct hip_ll_node *const node = *storage;

     if(node->ptr == ptr) {
         linkedlist->elementcount -= 1;
         *storage = node->next;

         free(node);
         // could return here for micro optimization
     } else {
         storage = &node->next;
     }
}

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

Hi,

On 20/02/12 22:03, Christof Mroz wrote:
> Review: Needs Fixing
>
>> === modified file 'lib/core/hostid.c'
>> --- lib/core/hostid.c 2011-11-10 10:35:47 +0000
>> +++ lib/core/hostid.c 2012-02-20 08:33:22 +0000
>> @@ -743,11 +744,17 @@
>> goto out_err;
>> }
>> } else if (!use_default) {
>> + char hi_file_dup[strlen(hi_file) + 1];
>> + strcpy(hi_file_dup, hi_file);
>> + if ((err = check_and_create_dir(dirname(hi_file_dup), HIP_DIR_MODE))) {
>> + HIP_ERROR("Could not create direcory for path: %s\n", hi_file);
>> + goto out_err;
>> + }
> I investigated a bit and seems like PATH_MAX is 4096 chars on linux, which is probably OK even for stacks on embedded devices, but strdup() would be safer nevertheless.
> My apologies for advising you to use the stack for that in the last mail (see also further below).
>
> Probably unrelated: should this handle recursive mkdir()? check_and_create_dir() currently does not, as far as I see.

Related stack memory usages have been reverted to malloc.

Regarding to check_and_create_dir(), in libhipl, using it is save,
because the parent directory (user's home folder) should exist.

Nice hints for linkedlist, it greatly shorten the lines of code :)

Xin

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

On Tue, Feb 21, 2012 at 05:36:57PM +0200, Xin Gu wrote:
> On 20/02/12 22:03, Christof Mroz wrote:
> >Review: Needs Fixing
> >
> >>=== modified file 'lib/core/hostid.c'
> >>--- lib/core/hostid.c 2011-11-10 10:35:47 +0000
> >>+++ lib/core/hostid.c 2012-02-20 08:33:22 +0000
> >>@@ -743,11 +744,17 @@
> >
> >Probably unrelated: should this handle recursive mkdir()? check_and_create_dir() currently does not, as far as I see.
>
> Regarding to check_and_create_dir(), in libhipl, using it is save,
> because the parent directory (user's home folder) should exist.

What happens if it does not exist?

Diego

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

On 21/02/12 21:21, Diego Biurrun wrote:
> On Tue, Feb 21, 2012 at 05:36:57PM +0200, Xin Gu wrote:
>> On 20/02/12 22:03, Christof Mroz wrote:
>>> Review: Needs Fixing
>>>
>>>> === modified file 'lib/core/hostid.c'
>>>> --- lib/core/hostid.c 2011-11-10 10:35:47 +0000
>>>> +++ lib/core/hostid.c 2012-02-20 08:33:22 +0000
>>>> @@ -743,11 +744,17 @@
>>> Probably unrelated: should this handle recursive mkdir()? check_and_create_dir() currently does not, as far as I see.
>> Regarding to check_and_create_dir(), in libhipl, using it is save,
>> because the parent directory (user's home folder) should exist.
> What happens if it does not exist?
>
>

Then the initialization process (loading the keys) will fail, program
exits with error.

Xin

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

Unless there's more to come (as you didn't request another review yet), I'm fine with the proposal.

Note that the early return in the linked list deletion routine is wrong if an item could be present multiple times.
In this case, in DEBUG configuration it could still be useful to trigger a HIP_ASSERT if an item is present multiple times but wasn't expected to (of course, you must always search the complete list then). This not directly related to this branch though.

If you commit the current version, remember to add bug tracker items concerning
- the non-recursive mkdir(): either always create the directory or never, but the current solution is something inbetween,
- the forking unit test: Even though forking is the simplest solution, tests should ideally not rely on their execution environment. Using mock functions you could also simulate dropped or corrupted packets for hipnetcat, etc.

review: Approve
Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Diego, I believe Xin has addressed the main issues, can we proceed to merge? We will continue to polish the library but we'd like to a get a more stable base for further work.

Revision history for this message
Stefan Götz (stefan.goetz-deactivatedaccount) wrote : Posted in a previous version of this proposal
Download full text (3.9 KiB)

 review needs-fixing

Sorry, Stefan the bean counter is back...
> /**
> + * Deletes the first node from list which has the same ptr given.

well, maybe "which contains the payload pointer ptr"?

> + * If there is no match, does nothing.
> + *
> + * @param linkedlist list to remoe an element from

remo[v]e

> + * @param ptr pointer by which to identify the node
> + * @param free_element a function pointer to a function for freeing the memory
> + * allocated for an element at a node or NULL if the element
> + * itself is not to be freed.
> + */
> +void hip_ll_del_by_ptr(struct hip_ll *linkedlist, void *ptr,
> + free_elem_fn free_element)

const correctness: struct hip_ll *const linkedlist, const void *const ptr

To separate memory management from list management, I would find it a cleaner
API to not pass in a free function pointer but to return a void* pointer. If ptr
was found in the list and removed, the function should then return ptr itself.
If ptr was not found in the list, the function should return NULL. In any case,
the caller can free the memory for ptr (if they intend to do so) by calling
free(hip_ll_del_by_ptr(list, ptr)); This separates concerns and is still very
easy to use.

> +{
> + struct hip_ll_node *curr;
> + struct hip_ll_node *tmp;
> +
> + /* match first list node */
> + if (linkedlist != NULL && linkedlist->element_count > 0

the check for linkedlist != NULL should also cover the second part of this
function. I'd suggest adding an assertion for it.

> + && linkedlist->head->ptr == ptr) {
> + tmp = linkedlist->head;
> + linkedlist->head = tmp->next;
> + linkedlist->element_count--;
> + if (free_element != NULL) {
> + free_element(tmp->ptr);
> + }
> + free(tmp);
> + return;
> + }
> +
> + /* match the rest list */

rest [of ]the list?

> + tmp = linkedlist->head;
> + for (curr = tmp->next; curr != NULL; curr = curr->next) {
> + if (curr->ptr == ptr) {
> + tmp->next = curr->next;
> + linkedlist->element_count--;
> + if (free_element != NULL) {
> + free_element(curr->ptr);
> + }
> + free(curr);
> + return;
> + }
> + tmp = tmp->next;
> + }
> +}

Why not go with Christof's version? It looked much simpler to me.

> +void hip_ll_del_by_ptr(struct hip_ll *linkedlist, void *ptr,
> + free_elem_fn free_element);

const correctness

> /**
> + * Read a control message over TCP socket.

What exactly does this function do? What happens after the message is read? Is
it returned to the caller? Sent to another processing function? /dev/null? The
CIA? Paradise?

> + * @param sockfd a socket file descriptor
> + * @param ctx a pointer to the packet context
> + * @return -1 in case of an error, 0 otherwise.
> + */
> +int hip_read_control_msg_tcp(int sockfd, struct hip_packet_context *ctx)

const correctness

> +int hip_read_control_msg_tcp(int sockfd, struct hip_packet_context *ctx);

const correctness

> --- h...

Read more...

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

On 26.02.2012 09:25, Stefan Götz wrote:
> To separate memory management from list management, I would find it a cleaner
> API to not pass in a free function pointer but to return a void* pointer. If ptr
> was found in the list and removed, the function should then return ptr itself.
> If ptr was not found in the list, the function should return NULL. In any case,
> the caller can free the memory for ptr (if they intend to do so) by calling
> free(hip_ll_del_by_ptr(list, ptr)); This separates concerns and is still very
> easy to use.

I'd rather vote for someone to pick up and finish your existing linked
list branch instead (one day), so we have a single implementation for
both hipd and hipfw.

I agree that passing the free function every time is stupid. Note though
that we could go the other extreme and store alloc/free function
pointers in the list head instead, to avoid this duplication altogether.
But ultimately your solution would wreak the least havoc, because there
is nothing unexpected going on behind the scenes (easier to comprehend
for new contributors) and we're unlikely to refactor this aspect.

>> +{
>> + struct hip_ll_node *curr;
>> + struct hip_ll_node *tmp;
>> +
>> + /* match first list node */
>> + if (linkedlist != NULL&& linkedlist->element_count> 0
>
> the check for linkedlist != NULL should also cover the second part of this
> function. I'd suggest adding an assertion for it.

Passing NULL to free()-like functions is usually a no-op (by
convention), so I disagree.

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Hi,

On 02/26/2012 01:50 PM, Christof Mroz wrote:
>>> +{
>>> + struct hip_ll_node *curr;
>>> + struct hip_ll_node *tmp;
>>> +
>>> + /* match first list node */
>>> + if (linkedlist != NULL&& linkedlist->element_count> 0
>>
>> the check for linkedlist != NULL should also cover the second part of
>> this
>> function. I'd suggest adding an assertion for it.
>
> Passing NULL to free()-like functions is usually a no-op (by
> convention), so I disagree.

don't know if this applies here but, in general, we have agreed that
calling free(NULL) in the context of e.g. HIP_IFEL() is fine as
indicated by doc/HACKING:

   int f(void)
   {
       char *mem = NULL;
       HIP_IFEL(!(mem = HIP_ALLOC(256, 0)), -1, "alloc\n");

   out_err:
       free(mem);
       return err;
   }

This keeps the line count at minimum.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

On Sat, Feb 25, 2012 at 09:52:17AM +0000, Miika Komu wrote:
> Diego, I believe Xin has addressed the main issues, can we proceed to
> merge? We will continue to polish the library but we'd like to a get a
> more stable base for further work.

No, the branch still has pending needs-fixing reviews and central issues
like the naming remain undecided.

Diego

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

Hi,

On 26/02/12 10:25, Stefan Götz wrote:
>> + * @param ptr pointer by which to identify the node
>> + * @param free_element a function pointer to a function for freeing the memory
>> + * allocated for an element at a node or NULL if the element
>> + * itself is not to be freed.
>> + */
>> +void hip_ll_del_by_ptr(struct hip_ll *linkedlist, void *ptr,
>> + free_elem_fn free_element)
> const correctness: struct hip_ll *const linkedlist, const void *const ptr

I was wondering if we can just use "const void *ptr"? I haven't figured
out why we need the second const.

If I understand correctly, you also suggest to change "struct
hip_packet_context *ctx" to "struct hip_packet_context *const ctx" for
the following function. Then I have the same question related to const
after asterisk.

int hip_read_control_msg_tcp(int sockfd, struct hip_packet_context *ctx)

> Why not go with Christof's version? It looked much simpler to me.

Current version is already based on Christof's advice. It seems that
somehow you receive an old version. I don't know why...

>> --- hipd/hadb.c 2012-02-17 10:45:47 +0000
>> +++ lib/hipdaemon/hadb.c 2012-02-20 08:33:22 +0000
>> @@ -616,7 +616,12 @@
>>
>> if (hip_select_source_address(&peer_map.our_addr,&peer_map.peer_addr)) {
>> HIP_ERROR("Cannot find source address\n");
>> - return -1;
>> + if (hipl_is_libhip_mode()) {
>> + memset(&peer_map.our_addr, 0, sizeof(peer_map.our_addr));
> How about 'peer_map.our_addr = INVALID_ADDR' with a suitable definition (and
> probably a better name for) INVALID_ADDR? It would reveal the intention of this
> code more clearly
>
>> + HIP_DEBUG("Using ANY for source address\n");
>> + } else {
>> + return -1;
>> + }

Hmm, what about add a comment? I add a comment and also rearrange this
part a bit, hope it is more clear.

> I couldn't finish reviewing, maybe later. In any case, const correctness for all
> further functions, please :)
>

I revised other code related to const correctness. Thanks for the review :)

https://code.launchpad.net/~hipl-core/hipl/libhip The diff in the
"Branch merges" section of this page is up-to-date.

Xin

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

Hi,

On 26/02/12 16:34, Diego Biurrun wrote:
> On Sat, Feb 25, 2012 at 09:52:17AM +0000, Miika Komu wrote:
>> Diego, I believe Xin has addressed the main issues, can we proceed to
>> merge? We will continue to polish the library but we'd like to a get a
>> more stable base for further work.
> No, the branch still has pending needs-fixing reviews and central issues
> like the naming remain undecided.
>
>

What is your opinion related to this naming issue? Previous we propose
to call it libhipl instead of libhipdaemon.
Since it will requires some efforts to change this, I hope we can agree
on a new name soon.

Xin

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

> I was wondering if we can just use "const void *ptr"? I haven't figured
> out why we need the second const.

http://www.parashift.com/c++-faq-lite/const-correctness.html

In short, 'const int *ptr' makes '*ptr = 7' illegal. 'int *const ptr' makes 'ptr
= NULL' illegal.

> If I understand correctly, you also suggest to change "struct
> hip_packet_context *ctx" to "struct hip_packet_context *const ctx" for
> the following function. Then I have the same question related to const
> after asterisk.
>
> int hip_read_control_msg_tcp(int sockfd, struct hip_packet_context *ctx)

Actually: const int sockfd, struct hip_packet_context *const ctx

Makes assignments to sockfd and ctx illegal because such assignments are not
necessary, anyway.

>> Why not go with Christof's version? It looked much simpler to me.
>
> Current version is already based on Christof's advice. It seems that
> somehow you receive an old version. I don't know why...

Ah, ok. No worries then.

>>> --- hipd/hadb.c 2012-02-17 10:45:47 +0000
>>> +++ lib/hipdaemon/hadb.c 2012-02-20 08:33:22 +0000
>>> @@ -616,7 +616,12 @@
>>>
>>> if (hip_select_source_address(&peer_map.our_addr,&peer_map.peer_addr)) {
>>> HIP_ERROR("Cannot find source address\n");
>>> - return -1;
>>> + if (hipl_is_libhip_mode()) {
>>> + memset(&peer_map.our_addr, 0, sizeof(peer_map.our_addr));
>> How about 'peer_map.our_addr = INVALID_ADDR' with a suitable definition (and
>> probably a better name for) INVALID_ADDR? It would reveal the intention of this
>> code more clearly
>>
>>> + HIP_DEBUG("Using ANY for source address\n");
>>> + } else {
>>> + return -1;
>>> + }
>
> Hmm, what about add a comment? I add a comment and also rearrange this
> part a bit, hope it is more clear.

Ok

Stefan

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Hi,

> Hi,
>
> On 26/02/12 16:34, Diego Biurrun wrote:
> > On Sat, Feb 25, 2012 at 09:52:17AM +0000, Miika Komu wrote:
> >> Diego, I believe Xin has addressed the main issues, can we proceed to
> >> merge? We will continue to polish the library but we'd like to a get a
> >> more stable base for further work.
> > No, the branch still has pending needs-fixing reviews and central issues
> > like the naming remain undecided.
> >
> >
>
> What is your opinion related to this naming issue? Previous we propose
> to call it libhipl instead of libhipdaemon.
> Since it will requires some efforts to change this, I hope we can agree
> on a new name soon.

I suggested earlier:
* lib/hipl for the directory hierarchy
* libhipl.{so.a} for the resulting binary

Diego, what say ye?

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

> /**
> + * Read a control message over TCP socket and save it to @c hip_packet_context
> + * for future processing.

Ideally, this would also describe at least the most important checks that this code performs, how it handles socket errors, etc.

> +int hip_read_control_msg_tcp(int sockfd, struct hip_packet_context *const ctx)

const sockfd

> + is_ipv4 = (src_addr.sa_family == AF_INET);
> + if (is_ipv4) {
> + saddr4 = (struct sockaddr_in *) &src_addr;
> + IPV4_TO_IPV6_MAP(&saddr4->sin_addr, &ctx->src_addr);
> + ctx->msg_ports.src_port = ntohs(saddr4->sin_port);
> + } else {
> + saddr6 = (struct sockaddr_in6 *) &src_addr;
> + memcpy(&ctx->dst_addr, &saddr6->sin6_addr, sizeof(struct in6_addr));

a plain assignment instead of memcpy is easier to read in such cases, but that is a matter of taste.

> + ctx->msg_ports.src_port = ntohs(saddr6->sin6_port);
> + }

Some of the socket_wrapper functions fit in very well here.

> + HIP_DEBUG_IN6ADDR("src", &ctx->src_addr);
> + HIP_DEBUG_IN6ADDR("dst", &ctx->dst_addr);

Maybe more information than that? Such as 'received packet from TCP socket, src..., dst...'?

> +static int hipd_library_mode = 0;

Why not a boolean type?

> === added file 'lib/hipdaemon/socket_wrapper.c'
> --- lib/hipdaemon/socket_wrapper.c 1970-01-01 00:00:00 +0000
> +++ lib/hipdaemon/socket_wrapper.c 2012-02-26 19:08:21 +0000

It would be extremely good to have more documentation in this file. Why is the struct hipl_fd_info necessary, for example? I don't mean what information in contains - that is obvious - but what is its purpose? Why was it necessary?

All of the functions in this file need to be updated with stricter const correctness.

> +static struct hip_ll socket_list;

What kind of socket is stored in this list? It's struct hipl_fd_info objects, right?

Are there many such objects? If not it may be simpler to just use a fixed size array than a dynamic list that tends to be awkward to use (==read).

> +static struct in6_addr default_hit;

> +/**
> + * Get information on a HIP socket by its file descritor.

descri[p]tor

Please use an editor with a spell checker and respect its suggestions :)

> +/**
> + * Add peer's hit-to-addr mapping to hadb.
> + * @param peer_hit peer's hit
> + * @param peer_addr peer's addr, v4 addr should be mapped.
> + * @return 0 on success, -1 otherwise.
> + */
> +int hipl_add_peer_info(const hip_hit_t *peer_hit,
> + const struct in6_addr *peer_addr)
> +{
> + return hip_hadb_add_peer_info(peer_hit, peer_addr, NULL, NULL);
> +}

What's the point? Why not call hip_hadb_add_peer_info() in the first place?

More to come

Stefan

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

On Mon, Feb 27, 2012 at 07:25:23AM +0000, Miika Komu wrote:
> > On 26/02/12 16:34, Diego Biurrun wrote:
> > > On Sat, Feb 25, 2012 at 09:52:17AM +0000, Miika Komu wrote:
> > >> Diego, I believe Xin has addressed the main issues, can we proceed to
> > >> merge? We will continue to polish the library but we'd like to a get a
> > >> more stable base for further work.
> > > No, the branch still has pending needs-fixing reviews and central issues
> > > like the naming remain undecided.
> >
> > What is your opinion related to this naming issue? Previous we propose
> > to call it libhipl instead of libhipdaemon.
> > Since it will requires some efforts to change this, I hope we can agree
> > on a new name soon.
>
> I suggested earlier:
> * lib/hipl for the directory hierarchy

I don't think grouping all of that stuff together below lib/ is a bad
idea, just put it in its separate directory.

I previously said I wanted to move lib/core and lib/tool together, I
would still like to.

> * libhipl.{so.a} for the resulting binary

Fine with me.

Diego

Revision history for this message
David Martin (martin-lp) wrote : Posted in a previous version of this proposal

Hi,

On Mon, Feb 27, 2012 at 9:04 AM, Stefan Götz <email address hidden> wrote:

>> +    is_ipv4 = (src_addr.sa_family == AF_INET);
>> +    if (is_ipv4) {
>> +        saddr4 = (struct sockaddr_in *) &src_addr;
>> +        IPV4_TO_IPV6_MAP(&saddr4->sin_addr, &ctx->src_addr);
>> +        ctx->msg_ports.src_port = ntohs(saddr4->sin_port);
>> +    } else {
>> +        saddr6 = (struct sockaddr_in6 *) &src_addr;
>> +        memcpy(&ctx->dst_addr, &saddr6->sin6_addr, sizeof(struct in6_addr));
>
> a plain assignment instead of memcpy is easier to read in such cases, but that is a matter of taste.

Either way there's a wrapper function for this purpose in
lib/core/prefix.c: ipv6_addr_copy(). Not sure if assignments are a
good idea but the wrapper should definitely be used instead of the
manual memcpy() with sizeof(). :)

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

On Mon, Feb 27, 2012 at 08:04:22AM +0000, Stefan Götz wrote:
> > + is_ipv4 = (src_addr.sa_family == AF_INET);
> > + if (is_ipv4) {
> > + saddr4 = (struct sockaddr_in *) &src_addr;
> > + IPV4_TO_IPV6_MAP(&saddr4->sin_addr, &ctx->src_addr);
> > + ctx->msg_ports.src_port = ntohs(saddr4->sin_port);
> > + } else {
> > + saddr6 = (struct sockaddr_in6 *) &src_addr;
> > + memcpy(&ctx->dst_addr, &saddr6->sin6_addr, sizeof(struct in6_addr));
>
> a plain assignment instead of memcpy is easier to read in such cases,
> but that is a matter of taste.

I'd disagree with the taste part - just use assignments.

Diego

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

Hi,

On 26/02/12 22:34, Stefan Götz wrote:
>> I was wondering if we can just use "const void *ptr"? I haven't figured
>> out why we need the second const.
> http://www.parashift.com/c++-faq-lite/const-correctness.html
>
> In short, 'const int *ptr' makes '*ptr = 7' illegal. 'int *const ptr' makes 'ptr
> = NULL' illegal.
>
>> If I understand correctly, you also suggest to change "struct
>> hip_packet_context *ctx" to "struct hip_packet_context *const ctx" for
>> the following function. Then I have the same question related to const
>> after asterisk.
>>
>> int hip_read_control_msg_tcp(int sockfd, struct hip_packet_context *ctx)
> Actually: const int sockfd, struct hip_packet_context *const ctx
>
> Makes assignments to sockfd and ctx illegal because such assignments are not
> necessary, anyway.
>
>

I understand the syntax of const, but from the caller's point of view,
it has no difference if the function parameters are "const int sockfd,
struct hip_packet_context *const ctx" or "int sockfd, struct
hip_packet_context *ctx". Because both integer and pointer are
pass-by-value, and callee changing those parameters or not won't affect
caller.

That's why I am wondering if it is really necessary to add const under
those situations, if we have a look at some other C libraries, it is
also rare to see them using const in this way. For example, socket(int,
int, int) not socket(const int, const int, const int).

Of course, a const pointer like "const char *ptr" is necessary, which
means the function will not alter the data this ptr points to. My commit
last night fixed the const missing for this case.

Xin

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Hi,

On 02/27/2012 10:23 AM, Diego Biurrun wrote:
> On Mon, Feb 27, 2012 at 07:25:23AM +0000, Miika Komu wrote:
>>> On 26/02/12 16:34, Diego Biurrun wrote:
>>>> On Sat, Feb 25, 2012 at 09:52:17AM +0000, Miika Komu wrote:
>>>>> Diego, I believe Xin has addressed the main issues, can we proceed to
>>>>> merge? We will continue to polish the library but we'd like to a get a
>>>>> more stable base for further work.
>>>> No, the branch still has pending needs-fixing reviews and central issues
>>>> like the naming remain undecided.
>>>
>>> What is your opinion related to this naming issue? Previous we propose
>>> to call it libhipl instead of libhipdaemon.
>>> Since it will requires some efforts to change this, I hope we can agree
>>> on a new name soon.
>>
>> I suggested earlier:
>> * lib/hipl for the directory hierarchy
>
> I don't think grouping all of that stuff together below lib/ is a bad
> idea, just put it in its separate directory.
>
> I previously said I wanted to move lib/core and lib/tool together, I
> would still like to.

I believe this request is unrelated to the merge proposal?

Anyway, we have decided earlier that lib/core contains MIT-licensed code
and lib/tool GPL-licensed code. Now that I think about this separation,
I think the copyright already states clearly the difference. So, I don't
really object against merging the two directories.

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Hi,

On 02/27/2012 11:27 AM, Xin Gu wrote:
> That's why I am wondering if it is really necessary to add const under
> those situations, if we have a look at some other C libraries, it is
> also rare to see them using const in this way. For example, socket(int,
> int, int) not socket(const int, const int, const int).

the Sockets API is a bit sloppy and we're trying to be more strict in HIPL.

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

Hi Xin,

your understanding is quite correct. It is simply project policy to make all data as 'const' as possible because it helps to detect bugs. For example:

void foo(list_t *list) {
  if (list = NULL) {
    return;
  } else {
    // do stuff with list
  }
}

cannot go unnoticed when foo is declared as 'void foo(list_t *const list)'

So you're right: such const qualifiers are not *necessary*. But the hipl team still considers them a very good idea.

Cheers,
 Stefan

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

On 27/02/12 11:46, Stefan Götz wrote:
> Hi Xin,
>
> your understanding is quite correct. It is simply project policy to make all data as 'const' as possible because it helps to detect bugs. For example:
>
> void foo(list_t *list) {
> if (list = NULL) {
> return;
> } else {
> // do stuff with list
> }
> }
>
> cannot go unnoticed when foo is declared as 'void foo(list_t *const list)'
>
> So you're right: such const qualifiers are not *necessary*. But the hipl team still considers them a very good idea.
>
> Cheers,
> Stefan
>
>

Hi Stefan,

Thanks for this explanation, so we are using const in this case for the
function author to avoid potential bugs and it is also helpful for
others to understand the code. It is a good practice, I will follow this
style.

I have one suggestion: for the function declaration in the header file,
I suggest that we can eliminate this kind of const because it makes no
sense for the API caller. For instance:

In linkedlist.h
void hip_ll_del_by_ptr(struct hip_ll *linkedlist, const void *ptr,
                        free_elem_fn free_element);

In linkedlist.c
void hip_ll_del_by_ptr(struct hip_ll *const linkedlist, const void
*const ptr,
                        free_elem_fn free_element) {
     ... ....
}

Compiler will treat them as the same function. I am also thinking if
there is any compiler option to enforce this const by default, then
perhaps we don't need to type it everywhere :)

Xin

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

On 27/02/12 10:04, Stefan Götz wrote:
>
>> + ctx->msg_ports.src_port = ntohs(saddr6->sin6_port);
>> + }
> Some of the socket_wrapper functions fit in very well here.

Didn't get your point, which function?

>
>> +static struct hip_ll socket_list;
> What kind of socket is stored in this list? It's struct hipl_fd_info objects, right?
>
> Are there many such objects? If not it may be simpler to just use a fixed size array than a dynamic list that tends to be awkward to use (==read).

Added comments about this field.

Yes, it is a list of hipl_fd_info. Since the number of open HIPL sockets
is determined by the user, I think it is difficult to make it as a fixed
size array.

>
>> +/**
>> + * Add peer's hit-to-addr mapping to hadb.
>> + * @param peer_hit peer's hit
>> + * @param peer_addr peer's addr, v4 addr should be mapped.
>> + * @return 0 on success, -1 otherwise.
>> + */
>> +int hipl_add_peer_info(const hip_hit_t *peer_hit,
>> + const struct in6_addr *peer_addr)
>> +{
>> + return hip_hadb_add_peer_info(peer_hit, peer_addr, NULL, NULL);
>> +}
> What's the point? Why not call hip_hadb_add_peer_info() in the first place?
>

This is an API for LIBHIPL user. We don't want user to directly handle hadb.

The const correctness is applied to all functions.

Xin

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

>>
>>> + ctx->msg_ports.src_port = ntohs(saddr6->sin6_port);
>>> + }
>> Some of the socket_wrapper functions fit in very well here.
>
> Didn't get your point, which function?

I meant get_port_from_saddr()

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

On 28/02/12 09:28, Stefan Götz wrote:
> I meant get_port_from_saddr()
>
>

This get_port_from_saddr() function is used when you don't know the
saddr is AF_INET or AF_INET6, and it is a static function, but in
currently condition we already know it is IPv4 or v6, because except
port number, we also extract the IP address from it.

Xin

Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

On 27/02/12 14:35, Diego Biurrun wrote:
> On Mon, Feb 27, 2012 at 11:31:45AM +0200, Miika Komu wrote:
>> On 02/27/2012 10:23 AM, Diego Biurrun wrote:
>> I believe this request is unrelated to the merge proposal?
> What to do with lib/core and lib/tool is, yes, but what to do with
> libhipl is not.
>
>
In libhip branch, I have changed libhipdaemon to libhipl, and renamed
folder from lib/hipdaemon to lib/hipl

Xin

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

Sorry, no time for more reviews :-(

review: Abstain
Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Unless somebody objects by Friday, I would suggest Xin to merge the code then.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

 review needs-fixing

On Tue, Mar 13, 2012 at 09:51:23AM +0000, Miika Komu wrote:
> Unless somebody objects by Friday, I would suggest Xin to merge the code then.

I object. This merge request had many comments and questions that I did
not see addressed. I would expect a fresh merge request at least.

Diego

review: Needs Fixing
Revision history for this message
Xin (eric-nevup) wrote : Posted in a previous version of this proposal

Hi,

On 13/03/12 17:58, Diego Biurrun wrote:
> I object. This merge request had many comments and questions that I did
> not see addressed. I would expect a fresh merge request at least.
>
Since all the reviewers approve this merge request, I don't know where
is the open comments and questions you said. If I miss something, could
you show them so I can fix accordingly?

Xin

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

On Wed, Mar 14, 2012 at 01:51:56PM +0200, Xin Gu wrote:
> On 13/03/12 17:58, Diego Biurrun wrote:
> >I object. This merge request had many comments and questions that I did
> >not see addressed. I would expect a fresh merge request at least.
> >
> Since all the reviewers approve this merge request,

I don't approve it and I set my review to needs-fixing.

> I don't know where is the open comments and questions you said. If I
> miss something, could you show them so I can fix accordingly?

As I said, I am expecting a fresh merge request; this one had far too
many comments.

Diego

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

> === modified file 'doc/HOWTO.xml.in'
> --- doc/HOWTO.xml.in 2012-01-25 10:44:48 +0000
> +++ doc/HOWTO.xml.in 2012-03-15 08:58:36 +0000
> @@ -2584,6 +2658,68 @@
> + <para>
> + Libhipl API set is mainly located in
> + <emphasis>"socket_wrapper.h"</emphasis>. The initialization function:
> + <emphasis>libhipd_init(void)</emphasis> is declared in
> + <emphasis>"init.h"</emphasis>
> + </para>

A <code> tag looks more appropriate than <emphasis> (also in other places throught the file)
http://www.docbook.org/tdg/en/html/code.html

> === added file 'lib/hipl/socket_wrapper.c'
> --- lib/hipl/socket_wrapper.c 1970-01-01 00:00:00 +0000
> +++ lib/hipl/socket_wrapper.c 2012-03-15 08:58:36 +0000
> @@ -0,0 +1,827 @@
> + do {
> + if (fd_info->proto == IPPROTO_TCP) {
> + if (!hip_read_control_msg_tcp(fd, &ctx)) {
> + hip_receive_control_packet(&ctx);
> + }
> + } else if (fd_info->family == AF_INET) {
> + if (!hip_read_control_msg_v4(fd, &ctx, HIP_UDP_ZERO_BYTES_LEN)) {
> + hip_receive_control_packet(&ctx);
> + }
> + } else {
> + if (!hip_read_control_msg_v6(fd, &ctx, HIP_UDP_ZERO_BYTES_LEN)) {
> + hip_receive_control_packet(&ctx);
> + }
> + }
> + } while (fd_info->ha->state != HIP_STATE_ESTABLISHED);

Looks like a lot of this dispatching throughout the patch could be avoided by introducing a generic hip_read_control_msg() function that takes an extra fd_info parameter and runs a switch() through it.
Sorry if this has been mentioned before, but I couldn't find it in the archives right away.

> + if (domain == AF_INET) {
> + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
> + setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
> + setsockopt(sock, IPPROTO_IP, IP_RECVERR, &off, sizeof(off));
> + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
> + } else {
> + setsockopt(sock, IPPROTO_IPV6, IPV6_RECVERR, &off, sizeof(off));
> + setsockopt(sock, IPPROTO_IPV6, IPV6_2292PKTINFO, &on, sizeof(on));
> + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
> + }

Since this is a library function (i.e., "user-friendly"), this should error out if neither AF_INET nor AF_INET6 are given.

> + /* Drop the packet if it doesn't come from the address associated
> + * with the correct peer. */
> + if (fd_info->proto == IPPROTO_UDP) {
> + if (addr->sa_family == AF_INET) {

Since this is a library function, you should check that addr is indeed non-NULL for UDP.
But better yet: don't use the caller's buffer in the first place but provide your own.

> + peer_addr4 = &((struct sockaddr_in *) addr)->sin_addr;
> + IPV4_TO_IPV6_MAP(peer_addr4, &peer_addr);
> + peer_addr6 = &peer_addr;
> + } else {

peer_addr is probably a useless indirection.

> === added file 'lib/hipl/socket_wrapper.h'
> --- lib/hipl/socket_wrapper.h 1970-01-01 00:00:00 +0000
> +++ lib/hipl/socket_wrapper.h 2012-03-15 08:58:36 +0000
> @@ -0,0 +1,52 @@
> +int hipl...

Read more...

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

We are currently wrapping up the changes to the HIPL codebase for our project in Aachen. To this end, we are testing the HIPL code thoroughly on the certificate-exchange branch (which is in close sync with trunk). You may have noticed some bug fixes during the last couple of days. Once, we are confident that the certificate-related code is working correctly, we will merge it to trunk.

In order to have a stable HIPL version at the end of our project, I would very much appreciate if you could delay your merge until the end of the month. This will give us enough time to fix remaining issues that we run into. Merging your branch will again result in hugh changes that may result in new bugs and additional effort towards a stabile version of HIPL.

I suggest to make a new HIPL release after the certificate code has been merged. A few people have asked for this functionality. So a release might be helpful for them. The next release may then consist of the librarized version of HIPL.

review: Disapprove
Revision history for this message
Miika Komu (miika-iki) wrote :

The code is actually supposed to improve testing but I do understand your concern. As a compromise, would it be ok to do an intermediate merge proposal where we just change the directory structure to reflect the upcoming changes with the library? This would ease our pain as well.

Regarding to the release, we can do a release from any version in the code base and there's no real reason why the release schedule should stall progress.

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

 review needs-fixing

On Thu, Mar 15, 2012 at 08:59:19AM +0000, Xin wrote:
> Xin has proposed merging lp:~hipl-core/hipl/libhip into lp:hipl.

This merge request is huge and not easy to review. Please split it.

> +++ Makefile.am 2012-03-15 08:58:36 +0000
> @@ -34,7 +34,7 @@
> EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/hipfw/,*.cfg))
> EXTRA_DIST += $(HIPL_HEADER_LIST)
> -EXTRA_DIST += hipd/pisa.c hipfw/pisa.c hipfw/pisa_cert.c
> +EXTRA_DIST += lib/hipl/pisa.c hipfw/pisa.c hipfw/pisa_cert.c

This conflicts with the certificate branch, which just landed on trunk.
You will have to merge trunk soon.

> @@ -48,6 +48,7 @@
>
> ### test programs ###
> noinst_PROGRAMS = test/certteststub \
> + test/hipnetcat \
> test/performance/auth_performance \

I think tools/ would be a better place for this.

> @@ -59,15 +60,19 @@
>
> ### libraries ###
> lib_LTLIBRARIES = lib/core/libhipcore.la
> +lib_LTLIBRARIES += lib/hipl/libhipl.la

Align the = please. Better yet, just put it on one line or continue
with a backslash, there is no need to split it like you did.

> @@ -85,46 +91,7 @@
>
> @@ -199,6 +166,48 @@
>
> +lib_hipl_libhipl_la_sources = lib/hipl/accessor.c \
> + lib/hipl/cert.c \
> + modules/heartbeat/hipd/heartbeat.c \
> + modules/heartbeat_update/hipd/hb_update.c \
> + modules/update/hipd/update.c \
> + modules/update/hipd/update_builder.c \
> + modules/update/hipd/update_locator.c \
> + modules/update/hipd/update_param_handling.c
> +
> +lib_hipl_libhipl_la_SOURCES = $(lib_hipl_libhipl_la_sources) \
> + modules/midauth/hipd/midauth.c

This looks like a merging error to me. I just made this indirection
unnecessary on trunk, midauth.c is just a normal source file.

> +lib_hipl_libhipl_la_LIBADD = lib/core/libhipcore.la

Place this together with the other lib dependencies.

> @@ -216,10 +225,13 @@
> test_check_lib_core_SOURCES = test/check_lib_core.c \
> test/lib/core/crypto.c \
> test/lib/core/hit.c \
> test/lib/core/hostid.c \
> + test/lib/core/linkedlist.c \

This whole linkedlist business could be split out into a separate merge request.

> --- doc/HOWTO.xml.in 2012-01-25 10:44:48 +0000
> +++ doc/HOWTO.xml.in 2012-03-15 08:58:36 +0000
> @@ -764,6 +764,80 @@
> </para>
> </section> <!-- handover -->
>
> + <section id="ch_hipnetcat">
> + <title>Test HIPL with the hipnetcat program</title>
> + <para>
> + Hipnetcat can be used to test the base exchange functionality of HIPL.
> + This section explains its usage in detail.
> + </para>
> +...

review: Needs Fixing
lp:~hipl-core/hipl/libhip updated
4889. By Xin

Check HIP firewall status before sending RESET message when closing HIP SA.

The "fail and retry" mechanism makes closing time unnecessary long when there
is no HIP firewall. In this case, we should simply skip this process.

4890. By Xin

Fix bug in hipnetcat test programming which causes longger testing time.

Previously, the break statement only exits the inner loop, but its purpose is
to exit the outer loop also.

4891. By Xin

Sync: trunk 6344

4892. By Xin

Eliminate redundant code in control message receiving and handling.

4893. By Xin

Fix issues in doc raised during review.

4894. By Xin

Sync: trunk 6360

4895. By Xin

Remove useless indirection.

Revision history for this message
Xin (eric-nevup) wrote :

Hi,

On 15/03/12 13:41, Christof Mroz wrote:
> Review: Needs Information
>
> A<code> tag looks more appropriate than<emphasis> (also in other places throught the file)
> http://www.docbook.org/tdg/en/html/code.html

Although from the link you provided, <code> tag can be the child of
<para>, I found that changing to <code> tag causes XML validation
failure. Now I still using <emphasis> tag.

> Since this is a library function (i.e., "user-friendly"), this should error out if neither AF_INET nor AF_INET6 are given.
>
> Since this is a library function, you should check that addr is indeed non-NULL for UDP.
> But better yet: don't use the caller's buffer in the first place but provide your own.
>
>
> Would a corresponding remove function make sense?

Next version of libhipl (which is what I am working on now) will contain
argument check and other functionalities you mentioned.

Other two issues: code redundancy and useless indirection are fixed.

Sorry for my delayed response. Thanks.

Xin

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

On Thu, Mar 22, 2012 at 02:49:47PM +0200, Xin Gu wrote:
> On 15/03/12 13:41, Christof Mroz wrote:
> >Review: Needs Information
> >
> >A<code> tag looks more appropriate than<emphasis> (also in other places throught the file)
> >http://www.docbook.org/tdg/en/html/code.html
>
> Although from the link you provided, <code> tag can be the child of
> <para>, I found that changing to <code> tag causes XML validation
> failure. Now I still using <emphasis> tag.

That is not the right solution. Look around in the file for better markup
suggestions.

Diego

lp:~hipl-core/hipl/libhip updated
4896. By Xin

sync: libhipl-mobility 4899

4897. By Xin

change the type of hipl_socket identifier from int to type hipl_sock_id

4898. By Xin

Sync: libhipl-mobility 4911.

4899. By Xin

Sync: trunk 6364

4900. By Xin

Fix document style and missing header.

4901. By Xin

Improve code style and doxygen documentation.

4902. By Xin

sync: trunk 6370

4903. By Xin

Remove unnecessary changes.

4904. By Xin

Change memcpy to assignments

4905. By Xin

Remove hipnetcat

Revision history for this message
Xin (eric-nevup) wrote :

Hi,

On 19/03/12 16:59, Diego Biurrun wrote:
> review needs-fixing
>
>
>> --- lib/core/hostid.c 2012-03-01 14:26:43 +0000
>> +++ lib/core/hostid.c 2012-03-15 08:58:36 +0000
>> @@ -678,6 +679,7 @@
>> int dsa_pub_key_rr_len = 0, rsa_pub_key_rr_len = 0;
>> hip_hdr numeric_action = 0;
>> + char *hi_file_dup = NULL;
>> char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];
>> @@ -743,11 +745,16 @@
>> goto out_err;
>> }
>> } else if (!use_default) {
>> + hi_file_dup = strdup(hi_file);
>> + if ((err = check_and_create_dir(dirname(hi_file_dup), HIP_DIR_MODE))) {
>> + HIP_ERROR("Could not create direcory for path: %s\n", hi_file);
>> + goto out_err;
> You strup - why?

the function dirname() might modify the parameter, so I copy it.

>
> unrelated: I'm slightly suspicious of HIP_DIR_MODE, which is 0755.
> Is it really safe to make this world-readable?
>

It seems to be problematic, what should be a safe DIR_MODE?

>
>> @@ -523,6 +551,208 @@
>> +static int libhip_init_handle_functions(void)
>> +{
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_I2, HIP_STATE_NONE,&hip_setup_ipsec_sa, 30500);
>> + //hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT,&hip_setup_ipsec_sa, 30500);
> Why are all these commented-out?

Because kernel-based IPSec functions cannot be used in libhipl. Now I
delete those lines instead of commenting out.

All other issues are fixed.
Although hipnetcat and its test cases are not included in the merge
proposal this time, I fixed those issues you mentioned. You will see
them when I merge the hipnetcat.

Thanks for the review.

Xin

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

On 17.04.2012 18:16, Xin wrote:
> On 19/03/12 16:59, Diego Biurrun wrote:
>> > review needs-fixing
>> >
>> >
>>> >> --- lib/core/hostid.c 2012-03-01 14:26:43 +0000
>>> >> +++ lib/core/hostid.c 2012-03-15 08:58:36 +0000
>>> >> @@ -678,6 +679,7 @@
>>> >> int dsa_pub_key_rr_len = 0, rsa_pub_key_rr_len = 0;
>>> >> hip_hdr numeric_action = 0;
>>> >> + char *hi_file_dup = NULL;
>>> >> char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];
>>> >> @@ -743,11 +745,16 @@
>>> >> goto out_err;
>>> >> }
>>> >> } else if (!use_default) {
>>> >> + hi_file_dup = strdup(hi_file);
>>> >> + if ((err = check_and_create_dir(dirname(hi_file_dup), HIP_DIR_MODE))) {
>>> >> + HIP_ERROR("Could not create direcory for path: %s\n", hi_file);
>>> >> + goto out_err;
>> > You strup - why?
> the function dirname() might modify the parameter, so I copy it.
>

This is ok now, but tucking the strdup() and dirname() away into
check_and_create_dir() could be less distracting and reusable. I'm not sure.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile.am'
--- Makefile.am 2012-03-13 15:27:06 +0000
+++ Makefile.am 2012-04-17 15:16:21 +0000
@@ -58,17 +58,21 @@
5858
5959
60### libraries ###60### libraries ###
61lib_LTLIBRARIES = lib/core/libhipcore.la61lib_LTLIBRARIES = lib/core/libhipcore.la \
62 lib/hipl/libhipl.la
6263
6364
64### tests ###65### tests ###
65if HIP_UNITTESTS66if HIP_UNITTESTS
66TESTS = test/check_hipd \67TESTS = test/check_hipd \
67 test/check_hipfw \68 test/check_hipfw \
68 test/check_lib_core69 test/check_lib_core \
70 test/check_libhipl
71
69check_PROGRAMS = test/check_hipd \72check_PROGRAMS = test/check_hipd \
70 test/check_hipfw \73 test/check_hipfw \
71 test/check_lib_core74 test/check_lib_core \
75 test/check_libhipl
72endif76endif
7377
7478
@@ -85,47 +89,7 @@
8589
86tools_hipconf_SOURCES = tools/hipconf.c90tools_hipconf_SOURCES = tools/hipconf.c
8791
88hipd_hipd_sources = hipd/accessor.c \92hipd_hipd_SOURCES = hipd/main.c
89 hipd/cert.c \
90 hipd/close.c \
91 hipd/configfilereader.c \
92 hipd/cookie.c \
93 hipd/dh.c \
94 hipd/esp_prot_anchordb.c \
95 hipd/esp_prot_hipd_msg.c \
96 hipd/esp_prot_light_update.c \
97 hipd/hadb.c \
98 hipd/hidb.c \
99 hipd/hip_socket.c \
100 hipd/hipd.c \
101 hipd/hiprelay.c \
102 hipd/hit_to_ip.c \
103 hipd/init.c \
104 hipd/input.c \
105 hipd/keymat.c \
106 hipd/lsidb.c \
107 hipd/maintenance.c \
108 hipd/nat.c \
109 hipd/netdev.c \
110 hipd/nsupdate.c \
111 hipd/opp_mode.c \
112 hipd/output.c \
113 hipd/pkt_handling.c \
114 hipd/registration.c \
115 hipd/user.c \
116 hipd/user_ipsec_hipd_msg.c \
117 hipd/user_ipsec_sadb_api.c \
118 modules/heartbeat/hipd/heartbeat.c \
119 modules/heartbeat_update/hipd/hb_update.c \
120 modules/cert/hipd/cert.c \
121 modules/update/hipd/update.c \
122 modules/update/hipd/update_builder.c \
123 modules/update/hipd/update_locator.c \
124 modules/update/hipd/update_param_handling.c
125
126hipd_hipd_SOURCES = $(hipd_hipd_sources) \
127 modules/midauth/hipd/midauth.c \
128 hipd/main.c
12993
130dist_sysconf_DATA = hipd/hipd.conf \94dist_sysconf_DATA = hipd/hipd.conf \
131 hipd/hosts \95 hipd/hosts \
@@ -202,6 +166,47 @@
202lib_core_libhipcore_la_SOURCES += lib/core/performance.c166lib_core_libhipcore_la_SOURCES += lib/core/performance.c
203endif167endif
204168
169lib_hipl_libhipl_la_SOURCES = lib/hipl/accessor.c \
170 lib/hipl/cert.c \
171 lib/hipl/close.c \
172 lib/hipl/configfilereader.c \
173 lib/hipl/cookie.c \
174 lib/hipl/dh.c \
175 lib/hipl/esp_prot_anchordb.c \
176 lib/hipl/esp_prot_hipd_msg.c \
177 lib/hipl/esp_prot_light_update.c \
178 lib/hipl/hadb.c \
179 lib/hipl/hidb.c \
180 lib/hipl/hip_socket.c \
181 lib/hipl/hipd.c \
182 lib/hipl/hiprelay.c \
183 lib/hipl/hit_to_ip.c \
184 lib/hipl/init.c \
185 lib/hipl/input.c \
186 lib/hipl/keymat.c \
187 lib/hipl/lhipl.c \
188 lib/hipl/lhipl_sock.c \
189 lib/hipl/lhipl_operations.c \
190 lib/hipl/lsidb.c \
191 lib/hipl/maintenance.c \
192 lib/hipl/nat.c \
193 lib/hipl/netdev.c \
194 lib/hipl/nsupdate.c \
195 lib/hipl/opp_mode.c \
196 lib/hipl/output.c \
197 lib/hipl/pkt_handling.c \
198 lib/hipl/registration.c \
199 lib/hipl/user.c \
200 lib/hipl/user_ipsec_hipd_msg.c \
201 lib/hipl/user_ipsec_sadb_api.c \
202 modules/cert/hipd/cert.c \
203 modules/heartbeat/hipd/heartbeat.c \
204 modules/heartbeat_update/hipd/hb_update.c \
205 modules/midauth/hipd/midauth.c \
206 modules/update/hipd/update.c \
207 modules/update/hipd/update_builder.c \
208 modules/update/hipd/update_locator.c \
209 modules/update/hipd/update_param_handling.c
205210
206test_check_hipd_SOURCES = test/check_hipd.c \211test_check_hipd_SOURCES = test/check_hipd.c \
207 test/hipd/lsidb.c \212 test/hipd/lsidb.c \
@@ -230,14 +235,18 @@
230 test/lib/core/gpl/pk.c \235 test/lib/core/gpl/pk.c \
231 test/lib/core/modules/midauth_builder.c236 test/lib/core/modules/midauth_builder.c
232237
238test_check_libhipl_SOURCES = test/check_libhipl.c
239
233240
234### static library dependencies ###241### static library dependencies ###
235242
236hipd_hipd_LDADD = lib/core/libhipcore.la243hipd_hipd_LDADD = lib/hipl/libhipl.la
237hipfw_hipfw_LDADD = lib/core/libhipcore.la244hipfw_hipfw_LDADD = lib/core/libhipcore.la
238test_check_hipd_LDADD = lib/core/libhipcore.la245lib_hipl_libhipl_la_LIBADD = lib/core/libhipcore.la
246test_check_hipd_LDADD = lib/hipl/libhipl.la
239test_check_hipfw_LDADD = lib/core/libhipcore.la247test_check_hipfw_LDADD = lib/core/libhipcore.la
240test_check_lib_core_LDADD = lib/core/libhipcore.la248test_check_lib_core_LDADD = lib/core/libhipcore.la
249test_check_libhipl_LDADD = lib/hipl/libhipl.la
241test_certteststub_LDADD = lib/core/libhipcore.la250test_certteststub_LDADD = lib/core/libhipcore.la
242test_performance_auth_performance_LDADD = lib/core/libhipcore.la251test_performance_auth_performance_LDADD = lib/core/libhipcore.la
243test_performance_dh_performance_LDADD = lib/core/libhipcore.la252test_performance_dh_performance_LDADD = lib/core/libhipcore.la
244253
=== modified file 'doc/HOWTO.xml.in'
--- doc/HOWTO.xml.in 2012-02-28 18:38:18 +0000
+++ doc/HOWTO.xml.in 2012-04-17 15:16:21 +0000
@@ -2659,6 +2659,112 @@
26592659
2660 </section>2660 </section>
26612661
2662 <section id="ch_libhipl_usage">
2663 <title>The Libhipl Extension</title>
2664
2665 <para>
2666 Libhipl provides HIP functionality as a library for upper layer
2667 applications and it does not require the presence of the HIPL daemon.
2668 Instead, the HIP control messages are transmitted on top of TCP/UDP.
2669 From the applications' point of view, there is an API similar to the
2670 normal socket API. This section describes the libhipl API.
2671 </para>
2672
2673 <para>
2674 Libhipl API set is located in <emphasis>"lhipl.h"</emphasis>. Refer to
2675 its API documentation for detail information of each function.
2676 </para>
2677
2678 <formalpara>
2679 <title>Libhipl initialization</title>
2680 <para>
2681 Libhipl requires initialization before calling any other related
2682 functions. The function: <emphasis>hipl_lib_init_all()</emphasis>
2683 serves this purpose and different debug levels can be set as its
2684 parameters to track problems inside the library.
2685 </para>
2686 </formalpara>
2687
2688 <formalpara>
2689 <title>Name-based API</title>
2690 <para>
2691 Compared to standard socket API, one apparent difference in Libhipl is
2692 that a peer is specified by given a peer name and a port number instead
2693 of a sockaddr data structure. The peer name is a string representation of
2694 the peer. Currently, Libhipl only support HIT string as peer name.
2695 </para>
2696 </formalpara>
2697
2698 <formalpara>
2699 <title>Libhipl socket creation</title>
2700 <para>
2701 The function hipl_socket() creates a new libhipl socket. An ID is
2702 assigned to each created libhipl socket and returned by this function,
2703 then caller can pass this ID to other libhipl functions to operates on
2704 this libhipl socket. NOTE: there is NO relation between libhipl socket
2705 ID and normal socket file descriptor, and the result of using
2706 this ID as file descriptor is undefined.
2707 </para>
2708 </formalpara>
2709
2710 <formalpara><title>Setup TCP connection</title><para>
2711 When using libhipl in TCP mode, TCP connection setup is the first task.
2712 similar to the normal socket syntax, libhipl provides:
2713 <emphasis>hipl_connect()</emphasis>, <emphasis>hipl_listen()</emphasis>
2714 and <emphasis>hipl_accept()</emphasis> for this goal. Those functions
2715 process the 3-way handshake and establish a TCP connection.
2716 </para></formalpara>
2717
2718 <formalpara>
2719 <title>libhipl Base Exchange (BEX) and user data transmission</title>
2720 <para>
2721 Data transmission is handled by <emphasis>hipl_sendto()</emphasis> and
2722 <emphasis>hipl_recvfrom()</emphasis>.
2723 In libhipl, The first sending data call triggers BEX and the first
2724 receiving call waits for incoming BEX message. Once BEX succeeds,
2725 the pending user data is transmitted to the peer side. This BEX process
2726 is handled by libhipl automatically by default. Meanwhile, we also
2727 provide an advanced way to handle BEX step by step, which we will
2728 explain bellow.
2729 </para>
2730 </formalpara>
2731
2732 <formalpara>
2733 <title>libhipl assistant API</title>
2734 <para>
2735 <itemizedlist>
2736 <listitem>
2737 <para>
2738 <emphasis>hipl_add_peer_info()</emphasis> adds peer's HIT and IP
2739 address mappings to the database of libhipl. The library can use
2740 this information to look up peer's locator when a peer name is
2741 given.
2742 </para>
2743 </listitem>
2744
2745 <listitem>
2746 <para>
2747 <emphasis>hipl_lib_set_bex_feedback()</emphasis>: This function
2748 turns on/off the step-by-step process of BEX. By default, BEX
2749 feedback is off. When it is on, sending/receiving functions only
2750 process one BEX messages at a time, and give different return
2751 values to notify the progress of BEX.
2752 </para>
2753 </listitem>
2754 </itemizedlist>
2755 </para>
2756 </formalpara>
2757
2758 <formalpara>
2759 <title>Libhipl sample program</title>
2760 <para>
2761 For a libhipl usage example, refer to the
2762 <emphasis>check_libhipl</emphasis> program in the
2763 <emphasis>test</emphasis> directory.
2764 </para>
2765 </formalpara>
2766
2767 </section> <!-- ch_libhipl_usage -->
2662</chapter> <!-- ch_exp_extensions -->2768</chapter> <!-- ch_exp_extensions -->
26632769
2664</book>2770</book>
26652771
=== modified file 'hipd/main.c'
--- hipd/main.c 2011-11-03 09:21:12 +0000
+++ hipd/main.c 2012-04-17 15:16:21 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University.2 * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation5 * obtaining a copy of this software and associated documentation
@@ -32,10 +32,9 @@
32#include <unistd.h>32#include <unistd.h>
33#include <sys/types.h>33#include <sys/types.h>
3434
35
36#include "hipd/hipd.h"
37#include "init.h"
38#include "lib/core/debug.h"35#include "lib/core/debug.h"
36#include "lib/hipl/hipd.h"
37#include "lib/hipl/init.h"
3938
4039
41/**40/**
4241
=== modified file 'hipfw/hipfw.c'
--- hipfw/hipfw.c 2012-04-16 14:55:53 +0000
+++ hipfw/hipfw.c 2012-04-17 15:16:21 +0000
@@ -75,7 +75,7 @@
75#include "lib/core/performance.h"75#include "lib/core/performance.h"
76#include "lib/core/prefix.h"76#include "lib/core/prefix.h"
77#include "lib/core/util.h"77#include "lib/core/util.h"
78#include "hipd/hipd.h"78#include "lib/hipl/hipd.h"
79#include "config.h"79#include "config.h"
80#include "cache.h"80#include "cache.h"
81#include "cert.h"81#include "cert.h"
8282
=== modified file 'lib/core/hostid.c'
--- lib/core/hostid.c 2012-03-01 14:26:43 +0000
+++ lib/core/hostid.c 2012-04-17 15:16:21 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University.2 * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation5 * obtaining a copy of this software and associated documentation
@@ -29,6 +29,7 @@
29 */29 */
3030
31#include <errno.h>31#include <errno.h>
32#include <libgen.h>
32#include <stdint.h>33#include <stdint.h>
33#include <stdlib.h>34#include <stdlib.h>
34#include <string.h>35#include <string.h>
@@ -678,6 +679,7 @@
678 int err = 0, dsa_key_rr_len = 0, rsa_key_rr_len = 0;679 int err = 0, dsa_key_rr_len = 0, rsa_key_rr_len = 0;
679 int dsa_pub_key_rr_len = 0, rsa_pub_key_rr_len = 0;680 int dsa_pub_key_rr_len = 0, rsa_pub_key_rr_len = 0;
680 hip_hdr numeric_action = 0;681 hip_hdr numeric_action = 0;
682 char *hi_file_dup = NULL;
681 char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];683 char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];
682 const char *rsa_filenamebase = DEFAULT_HOST_RSA_KEY_FILE_BASE DEFAULT_ANON_HI_FILE_NAME_SUFFIX;684 const char *rsa_filenamebase = DEFAULT_HOST_RSA_KEY_FILE_BASE DEFAULT_ANON_HI_FILE_NAME_SUFFIX;
683 const char *dsa_filenamebase = DEFAULT_HOST_DSA_KEY_FILE_BASE DEFAULT_ANON_HI_FILE_NAME_SUFFIX;685 const char *dsa_filenamebase = DEFAULT_HOST_DSA_KEY_FILE_BASE DEFAULT_ANON_HI_FILE_NAME_SUFFIX;
@@ -743,11 +745,16 @@
743 goto out_err;745 goto out_err;
744 }746 }
745 } else if (!use_default) {747 } else if (!use_default) {
748 hi_file_dup = strdup(hi_file);
749 if ((err = check_and_create_dir(dirname(hi_file_dup), HIP_DIR_MODE))) {
750 HIP_ERROR("Could not create directory for path: %s\n", hi_file);
751 goto out_err;
752 }
746 if (!strcmp(hi_fmt, "dsa")) {753 if (!strcmp(hi_fmt, "dsa")) {
747 dsa_key = create_dsa_key(dsa_key_bits);754 dsa_key = create_dsa_key(dsa_key_bits);
748 HIP_IFEL(!dsa_key, -EINVAL,755 HIP_IFEL(!dsa_key, -EINVAL,
749 "Creation of DSA key failed.\n");756 "Creation of DSA key failed.\n");
750 if ((err = save_dsa_private_key(dsa_filenamebase, dsa_key))) {757 if ((err = save_dsa_private_key(hi_file, dsa_key))) {
751 HIP_ERROR("Saving of DSA key failed.\n");758 HIP_ERROR("Saving of DSA key failed.\n");
752 goto out_err;759 goto out_err;
753 }760 }
@@ -756,7 +763,7 @@
756 ecdsa_key = create_ecdsa_key(ecdsa_nid);763 ecdsa_key = create_ecdsa_key(ecdsa_nid);
757 HIP_IFEL(!ecdsa_key, -EINVAL,764 HIP_IFEL(!ecdsa_key, -EINVAL,
758 "Creation of ECDSA key failed.\n");765 "Creation of ECDSA key failed.\n");
759 if ((err = save_ecdsa_private_key(ecdsa_filenamebase, ecdsa_key))) {766 if ((err = save_ecdsa_private_key(hi_file, ecdsa_key))) {
760 HIP_ERROR("Saving of ECDSA key failed.\n");767 HIP_ERROR("Saving of ECDSA key failed.\n");
761 goto out_err;768 goto out_err;
762 }769 }
@@ -765,7 +772,7 @@
765 rsa_key = create_rsa_key(rsa_key_bits);772 rsa_key = create_rsa_key(rsa_key_bits);
766 HIP_IFEL(!rsa_key, -EINVAL,773 HIP_IFEL(!rsa_key, -EINVAL,
767 "Creation of RSA key failed.\n");774 "Creation of RSA key failed.\n");
768 if ((err = save_rsa_private_key(rsa_filenamebase, rsa_key))) {775 if ((err = save_rsa_private_key(hi_file, rsa_key))) {
769 HIP_ERROR("Saving of RSA key failed.\n");776 HIP_ERROR("Saving of RSA key failed.\n");
770 goto out_err;777 goto out_err;
771 }778 }
@@ -1093,6 +1100,7 @@
1093 change_key_file_perms(rsa_filenamebase_pub);1100 change_key_file_perms(rsa_filenamebase_pub);
1094 }1101 }
10951102
1103 free(hi_file_dup);
1096 free(dsa_host_id);1104 free(dsa_host_id);
1097 free(dsa_pub_host_id);1105 free(dsa_pub_host_id);
1098 free(rsa_host_id);1106 free(rsa_host_id);
10991107
=== added directory 'lib/hipl'
=== renamed file 'hipd/accessor.c' => 'lib/hipl/accessor.c'
=== renamed file 'hipd/accessor.h' => 'lib/hipl/accessor.h'
=== renamed file 'hipd/cert.c' => 'lib/hipl/cert.c'
=== renamed file 'hipd/cert.h' => 'lib/hipl/cert.h'
=== renamed file 'hipd/close.c' => 'lib/hipl/close.c'
=== renamed file 'hipd/close.h' => 'lib/hipl/close.h'
=== renamed file 'hipd/configfilereader.c' => 'lib/hipl/configfilereader.c'
=== renamed file 'hipd/configfilereader.h' => 'lib/hipl/configfilereader.h'
=== renamed file 'hipd/cookie.c' => 'lib/hipl/cookie.c'
=== renamed file 'hipd/cookie.h' => 'lib/hipl/cookie.h'
=== renamed file 'hipd/dh.c' => 'lib/hipl/dh.c'
=== renamed file 'hipd/dh.h' => 'lib/hipl/dh.h'
=== renamed file 'hipd/esp_prot_anchordb.c' => 'lib/hipl/esp_prot_anchordb.c'
=== renamed file 'hipd/esp_prot_anchordb.h' => 'lib/hipl/esp_prot_anchordb.h'
=== renamed file 'hipd/esp_prot_hipd_msg.c' => 'lib/hipl/esp_prot_hipd_msg.c'
=== renamed file 'hipd/esp_prot_hipd_msg.h' => 'lib/hipl/esp_prot_hipd_msg.h'
=== renamed file 'hipd/esp_prot_light_update.c' => 'lib/hipl/esp_prot_light_update.c'
=== renamed file 'hipd/esp_prot_light_update.h' => 'lib/hipl/esp_prot_light_update.h'
=== renamed file 'hipd/hadb.c' => 'lib/hipl/hadb.c'
--- hipd/hadb.c 2012-03-20 13:08:56 +0000
+++ lib/hipl/hadb.c 2012-04-17 15:16:21 +0000
@@ -608,9 +608,15 @@
608 HIP_HOST_ID_HOSTNAME_LEN_MAX - 1);608 HIP_HOST_ID_HOSTNAME_LEN_MAX - 1);
609 }609 }
610610
611 if (hip_select_source_address(&peer_map.our_addr, &peer_map.peer_addr)) {611 /* hip_select_source_address() is incompatible with libhipl, therefore we skip
612 * this function and set the source address in peer_map to the ANY source
613 * address.*/
614 if (!hipl_is_libhip_mode()
615 && hip_select_source_address(&peer_map.our_addr, &peer_map.peer_addr)) {
612 HIP_ERROR("Cannot find source address\n");616 HIP_ERROR("Cannot find source address\n");
613 return -1;617 return -1;
618 } else if (hipl_is_libhip_mode()) {
619 memset(&peer_map.our_addr, 0, sizeof(peer_map.our_addr));
614 }620 }
615621
616 if (hip_for_each_hi(hadb_add_peer_info_wrapper, &peer_map)) {622 if (hip_for_each_hi(hadb_add_peer_info_wrapper, &peer_map)) {
@@ -1451,6 +1457,10 @@
1451 */1457 */
1452void hip_delete_security_associations_and_sp(struct hip_hadb_state *const ha)1458void hip_delete_security_associations_and_sp(struct hip_hadb_state *const ha)
1453{1459{
1460 if (hipl_is_libhip_mode()) {
1461 return;
1462 }
1463
1454 // Delete previous security policies1464 // Delete previous security policies
1455 hip_delete_hit_sp_pair(&ha->hit_our, &ha->hit_peer, 1);1465 hip_delete_hit_sp_pair(&ha->hit_our, &ha->hit_peer, 1);
1456 hip_delete_hit_sp_pair(&ha->hit_peer, &ha->hit_our, 1);1466 hip_delete_hit_sp_pair(&ha->hit_peer, &ha->hit_our, 1);
@@ -1520,6 +1530,11 @@
1520 ha),1530 ha),
1521 -1, "Error while changing outbound security association\n");1531 -1, "Error while changing outbound security association\n");
15221532
1533 if (hipl_is_libhip_mode()) {
1534 HIP_DEBUG("No SP set up in library mode\n");
1535 goto out_err;
1536 }
1537
1523 // Create a new security policy pointing to SAs after SA setup1538 // Create a new security policy pointing to SAs after SA setup
1524 HIP_IFEL(hip_setup_hit_sp_pair(&ha->hit_peer,1539 HIP_IFEL(hip_setup_hit_sp_pair(&ha->hit_peer,
1525 &ha->hit_our,1540 &ha->hit_our,
15261541
=== renamed file 'hipd/hadb.h' => 'lib/hipl/hadb.h'
=== renamed file 'hipd/hidb.c' => 'lib/hipl/hidb.c'
--- hipd/hidb.c 2012-04-17 11:20:20 +0000
+++ lib/hipl/hidb.c 2012-04-17 15:16:21 +0000
@@ -596,13 +596,15 @@
596 hip_add_iface_local_route(&in6_lsi);596 hip_add_iface_local_route(&in6_lsi);
597597
598 /* Adding HITs and LSIs to the interface */598 /* Adding HITs and LSIs to the interface */
599 if (hip_add_iface_local_hit(&hit)) {599 if (!hipl_is_libhip_mode()) {
600 HIP_ERROR("Failed to add HIT to the device\n");600 if (hip_add_iface_local_hit(&hit)) {
601 return -1;601 HIP_ERROR("Failed to add HIT to the device\n");
602 }602 return -1;
603 if (hip_add_iface_local_hit(&in6_lsi)) {603 }
604 HIP_ERROR("Failed to add LSI to the device\n");604 if (hip_add_iface_local_hit(&in6_lsi)) {
605 return -1;605 HIP_ERROR("Failed to add LSI to the device\n");
606 return -1;
607 }
606 }608 }
607 }609 }
608610
609611
=== renamed file 'hipd/hidb.h' => 'lib/hipl/hidb.h'
=== renamed file 'hipd/hip_socket.c' => 'lib/hipl/hip_socket.c'
=== renamed file 'hipd/hip_socket.h' => 'lib/hipl/hip_socket.h'
=== renamed file 'hipd/hipd.c' => 'lib/hipl/hipd.c'
=== renamed file 'hipd/hipd.h' => 'lib/hipl/hipd.h'
--- hipd/hipd.h 2012-03-20 21:45:03 +0000
+++ lib/hipl/hipd.h 2012-04-17 15:16:21 +0000
@@ -27,6 +27,7 @@
27#define HIPL_HIPD_HIPD_H27#define HIPL_HIPD_HIPD_H
2828
29#include <netdb.h>29#include <netdb.h>
30#include <stdbool.h>
30#include <stdint.h>31#include <stdint.h>
31#include <netinet/in.h>32#include <netinet/in.h>
32#include <sys/types.h>33#include <sys/types.h>
@@ -80,4 +81,8 @@
80int hipd_parse_cmdline_opts(int argc, char *argv[], uint64_t * flags);81int hipd_parse_cmdline_opts(int argc, char *argv[], uint64_t * flags);
81int hipd_main(uint64_t flags);82int hipd_main(uint64_t flags);
8283
84/* libhip_mode accessor */
85bool hipl_is_libhip_mode(void);
86void hipl_set_libhip_mode(void);
87
83#endif /* HIPL_HIPD_HIPD_H */88#endif /* HIPL_HIPD_HIPD_H */
8489
=== renamed file 'hipd/hiprelay.c' => 'lib/hipl/hiprelay.c'
=== renamed file 'hipd/hiprelay.h' => 'lib/hipl/hiprelay.h'
=== renamed file 'hipd/hit_to_ip.c' => 'lib/hipl/hit_to_ip.c'
=== renamed file 'hipd/hit_to_ip.h' => 'lib/hipl/hit_to_ip.h'
=== renamed file 'hipd/init.c' => 'lib/hipl/init.c'
--- hipd/init.c 2012-04-16 14:47:42 +0000
+++ lib/hipl/init.c 2012-04-17 15:16:21 +0000
@@ -34,7 +34,9 @@
3434
35#include <errno.h>35#include <errno.h>
36#include <limits.h>36#include <limits.h>
37#include <pwd.h>
37#include <signal.h>38#include <signal.h>
39#include <stdbool.h>
38#include <stdint.h>40#include <stdint.h>
39#include <stdlib.h>41#include <stdlib.h>
40#include <string.h>42#include <string.h>
@@ -118,6 +120,34 @@
118#endif120#endif
119/** end ICMPV6_FILTER related stuff */121/** end ICMPV6_FILTER related stuff */
120122
123#define HIPL_USER_DIR ".hipl"
124#define HIPL_USER_RSA_KEY_NAME "hipl_lib_rsa_key"
125
126/* Flag to show if hipl is running in libhip mode (=1) or normal mode (=0).
127 *
128 * This variable should NOT be accessed directly. Always use the accessor
129 * functions instead.
130 */
131static bool hipd_library_mode = false;
132
133/**
134 * Test if the library mode is on.
135 *
136 * @return true if the library mode is on, false otherwise.
137 */
138bool hipl_is_libhip_mode(void)
139{
140 return hipd_library_mode;
141}
142
143/**
144 * Turn on library mode.
145 */
146void hipl_set_libhip_mode(void)
147{
148 hipd_library_mode = true;
149}
150
121/* Startup flags of the HIPD. Keep the around, for they will be used at exit */151/* Startup flags of the HIPD. Keep the around, for they will be used at exit */
122static uint64_t sflags;152static uint64_t sflags;
123153
@@ -523,6 +553,199 @@
523 lmod_register_packet_type(HIP_LUPDATE, "HIP_LUPDATE");553 lmod_register_packet_type(HIP_LUPDATE, "HIP_LUPDATE");
524}554}
525555
556static int libhip_init_handle_functions(void)
557{
558 HIP_DEBUG("Initialize handle functions for libhip.\n");
559
560 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_check_i1, 20000);
561 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_handle_i1, 30000);
562 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_update_retransmissions, 35000);
563 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_send_r1, 40000);
564 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_check_i1, 20000);
565 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_handle_i1, 30000);
566 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_update_retransmissions, 35000);
567 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_send_r1, 40000);
568 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_check_i1, 20000);
569 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_handle_i1, 30000);
570 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_update_retransmissions, 35000);
571 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_send_r1, 40000);
572 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_check_i1, 20000);
573 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_handle_i1, 30000);
574 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_update_retransmissions, 35000);
575 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_send_r1, 40000);
576 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_check_i1, 20000);
577 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_handle_i1, 30000);
578 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 35000);
579 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_send_r1, 40000);
580 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_check_i1, 20000);
581 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_handle_i1, 30000);
582 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_update_retransmissions, 35000);
583 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_send_r1, 40000);
584 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_check_i1, 20000);
585 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_handle_i1, 30000);
586 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_update_retransmissions, 35000);
587 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_send_r1, 40000);
588 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_check_i1, 20000);
589 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_handle_i1, 30000);
590 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_update_retransmissions, 35000);
591 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_send_r1, 40000);
592
593 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_check_i2, 20000);
594 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_handle_i2, 30000);
595 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_update_retransmissions, 30250);
596 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_create_r2, 40000);
597 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_add_rvs_reg_from, 41000);
598 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_hmac2_and_sign, 42000);
599 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_add_rvs_relay_to, 43000);
600 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_send_r2, 50000);
601 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_check_i2, 20000);
602 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_handle_i2, 30000);
603 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_update_retransmissions, 30250);
604 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_create_r2, 40000);
605 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_add_rvs_reg_from, 41000);
606 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_hmac2_and_sign, 42000);
607 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_add_rvs_relay_to, 43000);
608 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_send_r2, 50000);
609 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_check_i2, 20000);
610 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2_in_i2_sent, 21000);
611 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2, 30000);
612 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30250);
613 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_create_r2, 40000);
614 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_add_rvs_reg_from, 41000);
615 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_hmac2_and_sign, 42000);
616 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_add_rvs_relay_to, 43000);
617 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_send_r2, 50000);
618 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_check_i2, 20000);
619 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_handle_i2, 30000);
620 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_update_retransmissions, 30250);
621 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_create_r2, 40000);
622 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_add_rvs_reg_from, 41000);
623 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_hmac2_and_sign, 42000);
624 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_add_rvs_relay_to, 43000);
625 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_send_r2, 50000);
626 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_check_i2, 20000);
627 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_handle_i2, 30000);
628 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 30250);
629 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_create_r2, 40000);
630 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_add_rvs_reg_from, 41000);
631 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_hmac2_and_sign, 42000);
632 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_add_rvs_relay_to, 43000);
633 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_send_r2, 50000);
634 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_check_i2, 20000);
635 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_handle_i2, 30000);
636 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_update_retransmissions, 30250);
637 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_create_r2, 40000);
638 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_add_rvs_reg_from, 41000);
639 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_hmac2_and_sign, 42000);
640 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_add_rvs_relay_to, 43000);
641 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_send_r2, 50000);
642 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_check_i2, 20000);
643 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_handle_i2, 30000);
644 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_update_retransmissions, 30250);
645 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_create_r2, 40000);
646 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_add_rvs_reg_from, 41000);
647 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_hmac2_and_sign, 42000);
648 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_add_rvs_relay_to, 43000);
649 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_send_r2, 50000);
650 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_check_i2, 20000);
651 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_handle_i2, 30000);
652 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_update_retransmissions, 30250);
653 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_create_r2, 40000);
654 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_add_rvs_reg_from, 41000);
655 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_hmac2_and_sign, 42000);
656 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_add_rvs_relay_to, 43000);
657 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_send_r2, 50000);
658
659 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_check_r1, 20000);
660 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_r1, 30000);
661 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_update_retransmissions, 30500);
662 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_esp_info, 31000);
663 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_solution, 32000);
664 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_diffie_hellman, 33000);
665 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &esp_prot_r1_handle_transforms, 34000);
666 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_create_i2, 40000);
667 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_add_signed_echo_response, 41000);
668 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_mac_and_sign_handler, 42000);
669 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_add_unsigned_echo_response, 43000);
670 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_send_i2, 50000);
671 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_check_r1, 20000);
672 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_r1, 30000);
673 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30500);
674 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_esp_info, 31000);
675 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_solution, 32000);
676 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_diffie_hellman, 33000);
677 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &esp_prot_r1_handle_transforms, 34000);
678 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_create_i2, 40000);
679 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_add_signed_echo_response, 41000);
680 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_mac_and_sign_handler, 42000);
681 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_add_unsigned_echo_response, 43000);
682 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_send_i2, 50000);
683 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_check_r1, 20000);
684 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_r1, 30000);
685 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_update_retransmissions, 30500);
686 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_esp_info, 31000);
687 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_solution, 32000);
688 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_diffie_hellman, 33000);
689 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &esp_prot_r1_handle_transforms, 34000);
690 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_create_i2, 40000);
691 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_add_signed_echo_response, 41000);
692 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_mac_and_sign_handler, 42000);
693 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_add_unsigned_echo_response, 43000);
694 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_send_i2, 50000);
695 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_check_r1, 20000);
696 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_r1, 30000);
697 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_update_retransmissions, 30500);
698 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_esp_info, 31000);
699 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_solution, 32000);
700 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_diffie_hellman, 33000);
701 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &esp_prot_r1_handle_transforms, 34000);
702 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_create_i2, 40000);
703 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_add_signed_echo_response, 41000);
704 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_mac_and_sign_handler, 42000);
705 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_add_unsigned_echo_response, 43000);
706 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_send_i2, 50000);
707
708 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_check_r2, 20000);
709 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_handle_r2, 30000);
710 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30250);
711
712 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_check_notify, 20000);
713 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_handle_notify, 30000);
714 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I2_SENT, &hip_check_notify, 20000);
715 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I2_SENT, &hip_handle_notify, 30000);
716 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_R2_SENT, &hip_check_notify, 20000);
717 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_R2_SENT, &hip_handle_notify, 30000);
718 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_ESTABLISHED, &hip_check_notify, 20000);
719 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_ESTABLISHED, &hip_handle_notify, 30000);
720 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSING, &hip_check_notify, 20000);
721 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSING, &hip_handle_notify, 30000);
722 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_check_notify, 20000);
723 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_handle_notify, 30000);
724
725 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_check_packet, 20000);
726 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 25000);
727 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_create_response, 30000);
728 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_send_response, 40000);
729
730 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_check_packet, 20000);
731 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_update_retransmissions, 25000);
732 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_create_response, 30000);
733 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_send_response, 40000);
734
735 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_check_packet, 20000);
736 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_update_retransmissions, 25000);
737 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_handle_packet, 30000);
738
739 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_check_packet, 20000);
740 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_update_retransmissions, 25000);
741 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_handle_packet, 30000);
742
743 hip_register_handle_function(HIP_LUPDATE, HIP_STATE_ESTABLISHED, &esp_prot_handle_light_update, 20000);
744 hip_register_handle_function(HIP_LUPDATE, HIP_STATE_R2_SENT, &esp_prot_handle_light_update, 20000);
745
746 return 0;
747}
748
526static int init_handle_functions(void)749static int init_handle_functions(void)
527{750{
528 int err = 0;751 int err = 0;
@@ -1090,6 +1313,80 @@
1090}1313}
10911314
1092/**1315/**
1316 * Initialization function for libhipl.
1317 *
1318 * @param debug_level debug level for log output.
1319 * @return 0 on success, negative number on errors.
1320 */
1321int hipl_lib_init(enum logdebug debug_level)
1322{
1323 int err = 0;
1324 int keypath_len = 0;
1325 char *key_path = NULL;
1326 struct hip_common *msg = NULL;
1327 struct passwd *pwd;
1328
1329 hipl_set_libhip_mode();
1330 hip_nat_status = 1;
1331
1332 /* disable hip_firewall */
1333 lsi_status = HIP_MSG_LSI_OFF;
1334
1335 /* set the initial verbosity level */
1336 hip_set_logdebug(debug_level);
1337
1338 hip_init_hadb();
1339 hip_init_hostid_db();
1340 hip_netdev_init_addresses();
1341 libhip_init_handle_functions();
1342
1343 /* Load default key from ~/.hipl/ */
1344 if ((pwd = getpwuid(getuid())) == NULL) {
1345 return -1;
1346 }
1347
1348 /* +3 because we need 2 slashes and a NULL for termination */
1349 keypath_len = strlen(pwd->pw_dir) +
1350 strlen(HIPL_USER_DIR) +
1351 strlen(HIPL_USER_RSA_KEY_NAME) +
1352 strlen(DEFAULT_PUB_HI_FILE_NAME_SUFFIX) + 3;
1353 if ((key_path = malloc(keypath_len)) == NULL) {
1354 HIP_ERROR("malloc() failed\n");
1355 return -ENOMEM;
1356 }
1357
1358 HIP_IFEL(snprintf(key_path, keypath_len, "%s/%s/%s%s", pwd->pw_dir,
1359 HIPL_USER_DIR,
1360 HIPL_USER_RSA_KEY_NAME,
1361 DEFAULT_PUB_HI_FILE_NAME_SUFFIX) < 0,
1362 -1, "snprintf() failed");
1363
1364 HIP_DEBUG("Using key: %s\n", key_path);
1365 HIP_IFEL(!(msg = hip_msg_alloc()), -ENOMEM, "hip_msg_alloc()");
1366 if (hip_serialize_host_id_action(msg, ACTION_ADD, 0, 0, "rsa",
1367 key_path, 0, 0, 0)) {
1368 free(msg);
1369 HIP_IFEL(!(msg = hip_msg_alloc()), -ENOMEM, "hip_msg_alloc()");
1370 HIP_IFEL(hip_serialize_host_id_action(msg, ACTION_NEW, 0, 0, "rsa",
1371 key_path, RSA_KEY_DEFAULT_BITS,
1372 DSA_KEY_DEFAULT_BITS,
1373 ECDSA_DEFAULT_CURVE), -1,
1374 "Fail to create local key at %s.", key_path);
1375 free(msg);
1376 HIP_IFE(!(msg = hip_msg_alloc()), -ENOMEM);
1377 HIP_IFEL(hip_serialize_host_id_action(msg, ACTION_ADD, 0, 0, "rsa",
1378 key_path, 0, 0, 0), -1,
1379 "Fail to load local key at %s.", key_path);
1380 }
1381 HIP_IFE(hip_handle_add_local_hi(msg), -1);
1382
1383out_err:
1384 free(msg);
1385 free(key_path);
1386 return err;
1387}
1388
1389/**
1093 * create a socket to handle UDP encapsulation of HIP control1390 * create a socket to handle UDP encapsulation of HIP control
1094 * packets1391 * packets
1095 *1392 *
10961393
=== renamed file 'hipd/init.h' => 'lib/hipl/init.h'
--- hipd/init.h 2011-11-25 17:56:24 +0000
+++ lib/hipl/init.h 2012-04-17 15:16:21 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.2 * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation5 * obtaining a copy of this software and associated documentation
@@ -29,6 +29,8 @@
29#include <stdint.h>29#include <stdint.h>
30#include <netinet/in.h>30#include <netinet/in.h>
3131
32#include "lib/core/debug.h"
33
3234
33/* startup flags options to be configured via the command line */35/* startup flags options to be configured via the command line */
34#define HIPD_START_FOREGROUND (1 << 0)36#define HIPD_START_FOREGROUND (1 << 0)
@@ -60,4 +62,6 @@
60 int is_output);62 int is_output);
61void hip_exit(void);63void hip_exit(void);
6264
65int hipl_lib_init(enum logdebug);
66
63#endif /* HIPL_HIPD_INIT_H */67#endif /* HIPL_HIPD_INIT_H */
6468
=== renamed file 'hipd/input.c' => 'lib/hipl/input.c'
--- hipd/input.c 2012-04-17 11:20:20 +0000
+++ lib/hipl/input.c 2012-04-17 15:16:21 +0000
@@ -707,6 +707,11 @@
707 &ctx->src_addr);707 &ctx->src_addr);
708 }708 }
709709
710 if (hipl_is_libhip_mode()) {
711 ctx->msg_ports.src_port = ctx->hadb_entry->peer_udp_port;
712 ctx->msg_ports.dst_port = ctx->hadb_entry->local_udp_port;
713 }
714
710 hip_relay_add_rvs_to_ha(ctx->input_msg, ctx->hadb_entry);715 hip_relay_add_rvs_to_ha(ctx->input_msg, ctx->hadb_entry);
711716
712#ifdef CONFIG_HIP_RVS717#ifdef CONFIG_HIP_RVS
713718
=== renamed file 'hipd/input.h' => 'lib/hipl/input.h'
=== renamed file 'hipd/keymat.c' => 'lib/hipl/keymat.c'
=== renamed file 'hipd/keymat.h' => 'lib/hipl/keymat.h'
=== added file 'lib/hipl/lhipl.c'
--- lib/hipl/lhipl.c 1970-01-01 00:00:00 +0000
+++ lib/hipl/lhipl.c 2012-04-17 15:16:21 +0000
@@ -0,0 +1,536 @@
1/*
2 * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file contains the implementation of the libhipl public APIs.
29 */
30
31#define _BSD_SOURCE
32
33#include <errno.h>
34#include <fcntl.h>
35#include <string.h>
36#include <unistd.h>
37
38#include "lib/core/builder.h"
39#include "lib/core/ife.h"
40#include "lib/core/prefix.h"
41#include "close.h"
42#include "hadb.h"
43#include "init.h"
44#include "lhipl_sock.h"
45#include "lhipl_operations.h"
46#include "netdev.h"
47#include "output.h"
48#include "lhipl.h"
49
50
51/* A switch to turn off/on BEX feedback.
52 *
53 * If it is on, when the BEX process is conducted during "recvmsg" and "sendmsg",
54 * the intermediate result is returned to the caller.
55 * If it is off, "recvmsg" and "sendmsg" will only return after the message gets
56 * sent or received.
57 */
58static bool libhipl_bex_feedback;
59
60/**
61 * build a @c sockaddr_in6 address to store peer's HIT and port number from a
62 * string-based peer name and a port number.
63 *
64 * @param peername the string representation of a peer, only support HIT string
65 * currently.
66 * @param port the port of the peer.
67 * @param peer the @c sockaddr_in6 to hold peer's HIT and port number.
68 * @return 0 on success, -1 on error.
69 */
70static int build_peer_hit(const char *peername, const uint16_t port,
71 struct sockaddr_in6 *peer)
72{
73 if (!peername || !peer) {
74 HIP_ERROR("Invalid input\n");
75 return -1;
76 }
77
78 if (inet_pton(AF_INET6, peername, &peer->sin6_addr) != 1) {
79 HIP_ERROR("Failed to translate %s into HIT\n", peername);
80 }
81 peer->sin6_port = htons(port);
82 peer->sin6_family = AF_INET6;
83 return 0;
84}
85
86/**
87 * Initialize libhipl library.
88 *
89 * This function should be called before using libhipl.
90 *
91 * @param debug_level the debug level of the libhipl library.
92 * @return 0 on success, negative number on error.
93 */
94int hipl_lib_init_all(enum hipl_lib_loglv debug_level)
95{
96 hipl_hsock_init();
97 switch (debug_level) {
98 case HIPL_LIB_LOG_DEBUG:
99 return hipl_lib_init(LOGDEBUG_ALL);
100 case HIPL_LIB_LOG_INFO:
101 return hipl_lib_init(LOGDEBUG_MEDIUM);
102 case HIPL_LIB_LOG_ERROR:
103 return hipl_lib_init(LOGDEBUG_LOW);
104 case HIPL_LIB_LOG_NONE:
105 return hipl_lib_init(LOGDEBUG_NONE);
106 }
107
108 return -1;
109}
110
111/**
112 * Check the current state of the BEX feedback switch.
113 *
114 * @return true if the switch is on, false if it is off.
115 */
116bool hipl_lib_bex_feedback(void)
117{
118 return libhipl_bex_feedback;
119}
120
121/**
122 * Turn off/on the BEX feedback switch.
123 *
124 * @param val true to turn the switch on, false to turn it off.
125 */
126void hipl_lib_set_bex_feedback(bool val)
127{
128 libhipl_bex_feedback = val;
129}
130
131/**
132 * Turn on/off non-blocking feature for a libhipl socket.
133 *
134 * @param hsock_id ID of the libhipl socket.
135 * @param on true to turn on non-blocking, false otherwise.
136 * @return 0 on success, negative number on error.
137 */
138int hipl_lib_set_nonblock(const hipl_sock_id hsock_id, bool on)
139{
140 int flags;
141 struct hipl_sock *hsock = NULL;
142
143 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
144 HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id);
145 return -EBADF;
146 }
147
148 flags = fcntl(hsock->sock_fd, F_GETFL, 0);
149 if (on && !(flags & O_NONBLOCK)) {
150 fcntl(hsock->sock_fd, F_SETFL, flags | O_NONBLOCK);
151 } else if (!on && (flags & O_NONBLOCK)) {
152 fcntl(hsock->sock_fd, F_SETFL, flags & ~O_NONBLOCK);
153 }
154 return 0;
155}
156
157/**
158 * Return the corresponding socket file descriptor of a libhipl socket.
159 *
160 * @param hsock_id the ID of the libhipl socket
161 * @return socket file descriptor on success, -1 on error.
162 */
163int hipl_lib_get_sockfd(const hipl_sock_id hsock_id)
164{
165 struct hipl_sock *hsock = NULL;
166
167 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
168 HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id);
169 return -1;
170 }
171
172 return hsock->sock_fd;
173}
174
175/**
176 * Save peer's HIT-to-IP mapping.
177 *
178 * @param hit peer's hit.
179 * @param addr peer's IP address.
180 * @return 0 on success, -1 otherwise.
181 */
182int hipl_add_peer_info(const char *const hit, const char *const addr)
183{
184 struct in6_addr peer_hit, peer_addr6;
185 struct in_addr peer_addr4;
186
187 if (!hit || !addr) {
188 HIP_ERROR("Invalid argument\n");
189 return -1;
190 }
191 if (inet_pton(AF_INET6, hit, &peer_hit) != 1) {
192 HIP_ERROR("Invalid hit: %s\n", hit);
193 return -1;
194 }
195 if (!ipv6_addr_is_hit(&peer_hit)) {
196 HIP_ERROR("Invalid hit: %s\n", hit);
197 return -1;
198 }
199 if (inet_pton(AF_INET6, addr, &peer_addr6) != 1) {
200 if (inet_pton(AF_INET, addr, &peer_addr4) != 1) {
201 HIP_ERROR("Invalid address: %s\n", addr);
202 return -1;
203 }
204 IPV4_TO_IPV6_MAP(&peer_addr4, &peer_addr6);
205 }
206
207 return hip_hadb_add_peer_info(&peer_hit, &peer_addr6, NULL, NULL);
208}
209
210/**
211 * Create a libhipl socket.
212 *
213 * @param domain the domain of the libhipl socket (AF_INET / AF_INET6).
214 * @param type the type of the libhipl socket (SOCK_DGRAM / SOCK_STREAM).
215 * @param protocol the protocol (IPPROTO_UDP / IPPROTO_TCP).
216 * @return the ID of the new libhipl socket on success, negative
217 * number on error.
218 */
219int hipl_socket(const int domain, const int type, const int protocol)
220{
221 if (domain != AF_INET && domain != AF_INET6) {
222 HIP_ERROR("Invalid domain: %d\n", domain);
223 return -EINVAL;
224 }
225 if (type != SOCK_DGRAM && type != SOCK_STREAM) {
226 HIP_ERROR("Invalid type: %d\n", type);
227 return -EINVAL;
228 }
229 if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) {
230 HIP_ERROR("Invalid protocol: %d\n", protocol);
231 return -EINVAL;
232 }
233
234 return hipl_socket_internal(domain, type, protocol);
235}
236
237/**
238 * Close a socket.
239 *
240 * Send HIP CLOSE message to the associated peer and deletes the libhipl
241 * socket information.
242 *
243 * @param hsock_id the ID of the libhipl socket to be closed.
244 * @return 0 on success, negative number on error.
245 */
246int hipl_close(const hipl_sock_id hsock_id)
247{
248 int ret = 0;
249 struct hip_common *msg = NULL;
250 struct hipl_sock *hsock = NULL;
251
252 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
253 HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id);
254 return -1;
255 }
256 if (!hsock->ha || hsock->ha->state == HIP_STATE_CLOSED) {
257 HIP_DEBUG("Not sending CLOSE.\n");
258 goto skip_close_msg;
259 }
260
261 /* Build HIP_CLOSE message and send it to the peer */
262 if ((msg = hip_msg_alloc()) == NULL) {
263 HIP_ERROR("hip_msg_alloc() failed");
264 ret = -ENOMEM;
265 goto skip_close_msg;
266 }
267 if ((ret = hip_build_param_contents(msg, &hsock->peer_hit,
268 HIP_PARAM_HIT,
269 sizeof(hsock->peer_hit))) < 0) {
270 HIP_ERROR("hip_build_param_contents() failed\n");
271 goto skip_close_msg;
272 }
273 if ((ret = hip_send_close(msg, 1)) < 0) {
274 HIP_ERROR("hip_send_close() failed\n");
275 }
276
277skip_close_msg:
278 if (hsock) {
279 close(hsock->sock_fd);
280 hipl_hsock_delete_and_free(hsock);
281 }
282 free(msg);
283 return ret;
284}
285
286/**
287 * Bind a libhipl socket to a local IP address.
288 *
289 * @param hsock_id the ID of the libhipl socket.
290 * @param address the IP address to be bound.
291 * @param address_len the length of the @c address.
292 * @return 0 on success, negative number on error.
293 */
294int hipl_bind(const hipl_sock_id hsock_id, const struct sockaddr *const address,
295 const socklen_t address_len)
296{
297 struct hipl_sock *hsock;
298
299 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
300 HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id);
301 return -1;
302 }
303
304 return hipl_bind_internal(hsock, address, address_len);
305}
306
307/**
308 * Switch a libhipl socket to listening mode.
309 *
310 * @param hsock_id the ID of the libhipl socket.
311 * @param backlog the max length of the queue for pending connections.
312 * @return zero on success, negative number on error.
313 */
314int hipl_listen(const hipl_sock_id hsock_id, const int backlog)
315{
316 struct hipl_sock *hsock;
317
318 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
319 HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id);
320 return -1;
321 }
322
323 return listen(hsock->sock_fd, backlog);
324}
325
326/**
327 * Send data to a peer.
328 *
329 * Triggers base exchange if no HIP association exists.
330 * @note Data is currently sent unencrypted.
331 *
332 * @param hsock_id the ID of the libhipl socket for sending data.
333 * @param msg data to send.
334 * @param len size of the data.
335 * @param flags the flags of the socket function @c sendto().
336 * @param peername the string representation of the peer.
337 * @param port peer's port number.
338 * @return number of bytes sent on success, negative number on error.
339 */
340int hipl_sendto(const hipl_sock_id hsock_id, const void *const msg,
341 const size_t len, const int flags,
342 const char *const peername, uint16_t port)
343{
344 struct hipl_sock *hsock;
345 struct sockaddr_in6 peer;
346 struct msghdr params = { 0 };
347 struct iovec iov;
348 char *buf = NULL;
349 int err = 0;
350
351 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
352 HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id);
353 return -1;
354 }
355 if (hsock->sock_proto == IPPROTO_UDP
356 && (peername == NULL || build_peer_hit(peername, port, &peer) < 0)) {
357 HIP_ERROR("Invalid argument: peername\n");
358 return -EINVAL;
359 }
360 if (hsock->sock_proto == IPPROTO_TCP
361 && hsock->peer_locator.ss_family == 0) {
362 HIP_ERROR("Not connected!\n");
363 return -ENOTCONN;
364 }
365 if (msg == NULL) {
366 HIP_ERROR("Invalid argument: msg\n");
367 return -EINVAL;
368 }
369
370 struct sockaddr_storage dst;
371 struct sockaddr_in6 *p6;
372 if (hsock->sock_proto == IPPROTO_UDP) {
373 hipl_build_addrstorage(&peer.sin6_addr, ntohs(peer.sin6_port), &dst);
374 } else {
375 dst = hsock->peer_locator;
376 p6 = (struct sockaddr_in6 *) &dst;
377 p6->sin6_addr = hsock->peer_hit;
378 p6->sin6_family = AF_INET6;
379 }
380 if ((buf = malloc(len)) == NULL) {
381 return -ENOMEM;
382 }
383 memcpy(buf, msg, len);
384 iov.iov_base = buf;
385 iov.iov_len = len;
386 params.msg_name = &dst;
387 params.msg_namelen = sizeof(dst);
388 params.msg_iovlen = 1;
389 params.msg_iov = &iov;
390
391 if (hipl_lib_bex_feedback()) {
392 err = hipl_sendmsg_internal(hsock, &params, flags);
393 } else {
394 fd_set fdset;
395 if (hipl_hsock_ha_state(hsock) == HIP_STATE_UNASSOCIATED) {
396 HIP_DEBUG("Sending via hsock %d, Triggering BEX.\n", hsock->sid);
397 err = hipl_sendmsg_internal(hsock, &params, flags);
398 HIP_IFEL(err != -EWAITBEX, -1, "hipl_sendmsg_internal() failed\n");
399 }
400 if (hipl_hsock_ha_state(hsock) == HIP_STATE_ESTABLISHED) {
401 HIP_DEBUG("Sending via hsock %d, HA established.\n", hsock->sid);
402 err = hipl_sendmsg_internal(hsock, &params, flags);
403 } else {
404 while (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) {
405 FD_ZERO(&fdset);
406 FD_SET(hsock->sock_fd, &fdset);
407 HIP_DEBUG("Sending via hsock %d, Waiting BEX.\n", hsock->sid);
408 err = select(hsock->sock_fd + 1, &fdset, NULL, NULL, NULL);
409 HIP_IFEL(err < 0, -1, "select(): %s\n", strerror(errno));
410 err = hipl_sendmsg_internal(hsock, &params, flags);
411 HIP_IFEL(err < 0 && err != -EWAITBEX && err != -EBEXESTABLISHED,
412 -1, "hipl_sendmsg_internal() failed\n");
413 }
414 err = hipl_sendmsg_internal(hsock, &params, flags);
415 }
416 }
417
418out_err:
419 free(buf);
420 return err;
421}
422
423/**
424 * Receive data from a peer.
425 *
426 * Wait for base exchange if no host association exists.
427 * @note Data is currently sent unencrypted.
428 *
429 * @param hsock_id the ID of the libhipl socket for receiving data.
430 * @param buf buffer for received data.
431 * @param len the size of the @c buf.
432 * @param flags the flags of the socket function @c recvfrom().
433 * @param peername buffer for the HIT of the associated peer, the size of
434 * this buffer should be at least @c HIPL_MAX_PEERNAME.
435 * @param port buffer for the port of the associated peer.
436 * @return number of bytes received on success,
437 * negative number on error,
438 * 0 on end-of-file.
439 */
440int hipl_recvfrom(const hipl_sock_id hsock_id, void *const buf,
441 const size_t len, const int flags,
442 char *const peername, uint16_t *const port)
443{
444 struct hipl_sock *hsock = NULL;
445 struct msghdr params = { 0 };
446 struct iovec iov;
447 struct sockaddr_in6 hit;
448 int ret;
449
450 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
451 HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id);
452 return -1;
453 }
454 if (hsock->sock_proto == IPPROTO_TCP
455 && hsock->peer_locator.ss_family == 0) {
456 HIP_ERROR("Not connected!\n");
457 return -ENOTCONN;
458 }
459
460 iov.iov_base = buf;
461 iov.iov_len = len;
462 params.msg_name = &hit;
463 params.msg_namelen = sizeof(hit);
464 params.msg_iovlen = 1;
465 params.msg_iov = &iov;
466
467 if (!hipl_lib_bex_feedback()) {
468 fd_set fdset;
469 while (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) {
470 FD_ZERO(&fdset);
471 FD_SET(hsock->sock_fd, &fdset);
472 if (select(hsock->sock_fd + 1, &fdset, NULL, NULL, NULL) < 0) {
473 HIP_PERROR("select()");
474 }
475 ret = hipl_recvmsg_internal(hsock, &params, flags);
476 if (ret < 0 && ret != -EWAITBEX && ret != -EBEXESTABLISHED) {
477 HIP_ERROR("hipl_recvmsg_internal() failed()\n");
478 return ret;
479 }
480 }
481 }
482 ret = hipl_recvmsg_internal(hsock, &params, flags);
483
484 if (peername) {
485 inet_ntop(AF_INET6, &hit.sin6_addr, peername, HIPL_MAX_PEERNAME);
486 }
487 if (port) {
488 *port = ntohs(hit.sin6_port);
489 }
490 return ret;
491}
492
493/**
494 * Initiate a connection to a peer.
495 *
496 * @param hsock_id the ID of the libhipl socket to initiate a connection.
497 * @param peername the string representation of the peer.
498 * @param port the port number of the peer.
499 * @return 0 on success, negative number on error.
500 */
501int hipl_connect(const hipl_sock_id hsock_id, const char *peername,
502 const uint16_t port)
503{
504 struct hipl_sock *hsock = NULL;
505 struct sockaddr_in6 peer;
506
507 if (peername == NULL || build_peer_hit(peername, port, &peer) < 0) {
508 HIP_ERROR("Invalid argument: peername\n");
509 return -EINVAL;
510 }
511 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
512 HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id);
513 return -1;
514 }
515
516 return hipl_connect_internal(hsock, &peer);
517}
518
519/**
520 * Wait for an incoming connection.
521 *
522 * @param hsock_id the ID of the libhipl socket for waiting connections.
523 * @return the ID of the accepted libhipl socket, negative number
524 * on error.
525 */
526int hipl_accept(const hipl_sock_id hsock_id)
527{
528 struct hipl_sock *hsock = NULL;
529
530 if ((hsock = hipl_hsock_find(hsock_id)) == NULL) {
531 HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id);
532 return -1;
533 }
534
535 return hipl_accept_internal(hsock);
536}
0537
=== added file 'lib/hipl/lhipl.h'
--- lib/hipl/lhipl.h 1970-01-01 00:00:00 +0000
+++ lib/hipl/lhipl.h 2012-04-17 15:16:21 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef HIPL_LIB_HIPL_LHIPL_H
27#define HIPL_LIB_HIPL_LHIPL_H
28
29#include <sys/socket.h>
30#include <stdbool.h>
31#include <stdint.h>
32
33
34#define EWAITBEX 139000
35#define EBEXESTABLISHED 139001
36
37#define HIPL_MAX_PEERNAME 128
38
39enum hipl_lib_loglv { HIPL_LIB_LOG_DEBUG, HIPL_LIB_LOG_INFO,
40 HIPL_LIB_LOG_ERROR, HIPL_LIB_LOG_NONE };
41
42typedef uint16_t hipl_sock_id;
43
44int hipl_lib_init_all(enum hipl_lib_loglv);
45
46void hipl_lib_set_bex_feedback(bool val);
47bool hipl_lib_bex_feedback(void);
48
49int hipl_lib_set_nonblock(const hipl_sock_id hsock_id, bool on);
50int hipl_lib_get_sockfd(const hipl_sock_id hsock_id);
51
52int hipl_add_peer_info(const char *const hit, const char *const addr);
53
54int hipl_socket(const int domain, const int type, const int protocol);
55
56int hipl_close(const hipl_sock_id hsock_id);
57
58int hipl_listen(const hipl_sock_id hsock_id, const int backlog);
59
60int hipl_bind(const hipl_sock_id hsock_id, const struct sockaddr *const address,
61 const socklen_t address_len);
62
63int hipl_sendto(const hipl_sock_id hsock_id, const void *const msg,
64 const size_t len, const int flags,
65 const char *const peername, const uint16_t port);
66
67int hipl_recvfrom(const hipl_sock_id hsock_id, void *const buf,
68 const size_t len, const int flags,
69 char *const peername, uint16_t *const port);
70
71int hipl_connect(const hipl_sock_id hsock_id, const char *const peername,
72 const uint16_t port);
73
74int hipl_accept(const hipl_sock_id hsock_id);
75
76#endif /* HIPL_LIB_HIPL_LHIPL_H */
077
=== added file 'lib/hipl/lhipl_operations.c'
--- lib/hipl/lhipl_operations.c 1970-01-01 00:00:00 +0000
+++ lib/hipl/lhipl_operations.c 2012-04-17 15:16:21 +0000
@@ -0,0 +1,771 @@
1/*
2 * Copyright (c) 2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file contains the internal implementation of the libhipl socket
29 * related operations.
30 */
31
32#define _BSD_SOURCE
33
34#include <sys/socket.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <stdbool.h>
38#include <string.h>
39#include <unistd.h>
40
41#include "lib/core/builder.h"
42#include "lib/core/hip_udp.h"
43#include "lib/core/ife.h"
44#include "lib/core/prefix.h"
45#include "lhipl.h"
46#include "lhipl_sock.h"
47#include "hadb.h"
48#include "hidb.h"
49#include "input.h"
50#include "netdev.h"
51#include "output.h"
52#include "lhipl_operations.h"
53
54
55/**
56 * Automatically bind to a port for a libhipl socket.
57 *
58 * @param hsock the libhipl socket for port binding.
59 * @return 0 on success, -1 on error.
60 */
61static int auto_bind(struct hipl_sock *const hsock)
62{
63 struct sockaddr_storage ss = { 0 };
64 struct sockaddr_in *addr4;
65 struct sockaddr_in6 *addr6;
66
67 if (hsock->src_port != 0) {
68 HIP_DEBUG("A bound port exists, auto_bind stops\n");
69 return 0;
70 }
71
72 if (hsock->sock_family == AF_INET) {
73 ss.ss_family = AF_INET;
74 addr4 = (struct sockaddr_in *) &ss;
75 addr4->sin_port = 0;
76 return hipl_bind_internal(hsock, (struct sockaddr *) addr4,
77 sizeof(ss));
78 } else {
79 ss.ss_family = AF_INET6;
80 addr6 = (struct sockaddr_in6 *) &ss;
81 addr6->sin6_port = 0;
82 return hipl_bind_internal(hsock, (struct sockaddr *) addr6,
83 sizeof(ss));
84 }
85}
86
87static uint16_t get_port_from_saddr(const struct sockaddr *const addr)
88{
89 const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
90 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
91
92 if (addr->sa_family == AF_INET) {
93 return addr4->sin_port;
94 } else {
95 return addr6->sin6_port;
96 }
97}
98
99/**
100 * Set global variables in order to inter-operate with libhipdeamon.
101 *
102 * @param sock_fd the socket file descriptor for sending message.
103 * @param local_port the local port for sending message.
104 * @param remote_port the remote port for receiving message.
105 */
106static void set_hip_connection_parameters(const int sock_fd,
107 const int local_port,
108 const int remote_port)
109{
110 HIP_DEBUG("Set connection params: fd = %d, lport = %d, rport= %d\n",
111 sock_fd, local_port, remote_port);
112 hip_nat_sock_output_udp = sock_fd;
113 hip_raw_sock_output_v4 = sock_fd;
114 hip_raw_sock_output_v6 = sock_fd;
115 hip_set_local_nat_udp_port(local_port);
116 hip_set_peer_nat_udp_port(remote_port);
117}
118
119/**
120 * Check whether a received packet is a HIP control packet.
121 *
122 * @param buf buffer containing the received packet.
123 * @param len size of the @c buf.
124 * @param hsock the libhipl socket receiving the packet.
125 * @return 1 on a control message, 0 on a user message,
126 * negative number on error.
127 */
128static int hipl_is_control_msg(char *const buf, unsigned int len,
129 struct hipl_sock *const hsock)
130{
131 char udp_pad[HIP_UDP_ZERO_BYTES_LEN] = { 0 };
132 struct hip_common *msg;
133 struct sockaddr_storage src = { 0 };
134 socklen_t srclen = sizeof(src);
135
136 if (len < sizeof(struct hip_common)) {
137 return 0;
138 }
139
140 if (!memcmp(udp_pad, buf, HIP_UDP_ZERO_BYTES_LEN)) {
141 HIP_DEBUG("Message is padded\n");
142 msg = (struct hip_common *) (buf + HIP_UDP_ZERO_BYTES_LEN);
143 len -= HIP_UDP_ZERO_BYTES_LEN;
144 } else {
145 msg = (struct hip_common *) buf;
146 }
147
148 if (getsockname(hsock->sock_fd, (struct sockaddr *) &src, &srclen) < 0) {
149 HIP_PERROR("getsockname()");
150 return true;
151 }
152
153 return !hip_verify_network_header(msg, (struct sockaddr *) &src,
154 (struct sockaddr *) &hsock->peer_locator,
155 len);
156}
157
158static void build_packet_context(struct hip_packet_context *const ctx,
159 struct sockaddr *ctx_dst, struct sockaddr *ctx_src)
160{
161 struct sockaddr_in *s4;
162 struct sockaddr_in6 *s6;
163
164 if (ctx_dst->sa_family == AF_INET) {
165 s4 = (struct sockaddr_in *) ctx_dst;
166 IPV4_TO_IPV6_MAP(&s4->sin_addr, &ctx->dst_addr);
167 ctx->msg_ports.dst_port = ntohs(s4->sin_port);
168 } else if (ctx_dst->sa_family == AF_INET6) {
169 s6 = (struct sockaddr_in6 *) ctx_dst;
170 ctx->dst_addr = s6->sin6_addr;
171 ctx->msg_ports.dst_port = ntohs(s6->sin6_port);
172 }
173
174 if (ctx_src->sa_family == AF_INET) {
175 s4 = (struct sockaddr_in *) ctx_src;
176 IPV4_TO_IPV6_MAP(&s4->sin_addr, &ctx->src_addr);
177 ctx->msg_ports.src_port = ntohs(s4->sin_port);
178 } else if (ctx_src->sa_family == AF_INET6) {
179 s6 = (struct sockaddr_in6 *) ctx_src;
180 ctx->src_addr = s6->sin6_addr;
181 ctx->msg_ports.src_port = ntohs(s6->sin6_port);
182 }
183}
184
185/**
186 * Receive and pre-process an incoming message.
187 *
188 * This function discards UDP packet from an unknown peer, identifies
189 * user/control packet, eliminates zero padding in control packets and
190 * builds the packet context for handling control packets.
191 *
192 * @param hsock the libhipl socket for receiving message.
193 * @param msg buffer to hold the incoming message.
194 * @param flags the flags of socket @c recvmsg().
195 * @param ctx the HIP packet context to be built.
196 * @param is_user_msg true if the message is a user message, false otherwise.
197 * @return negative number on errors, 0 on end-of-file, number of
198 * bytes received otherwise.
199 */
200static int recv_msg_wrapper(struct hipl_sock *const hsock,
201 struct msghdr *const msg, const int flags,
202 struct hip_packet_context *const ctx,
203 bool *is_user_msg)
204{
205 int ret;
206 struct sockaddr_storage our_locator = { 0 };
207 socklen_t sslen = sizeof(our_locator);
208
209 *is_user_msg = true;
210 if ((ret = recvmsg(hsock->sock_fd, msg, flags)) < 0) {
211 HIP_PERROR("recvmsg()");
212 return -1;
213 }
214
215 //in UDP mode, we don't know the peer locator until we receive the
216 //first message from the peer. Once we get the peer locator, save it
217 //to 'hsock'. We should also fill the packet context for UDP.
218 if (hsock->sock_proto == IPPROTO_UDP) {
219 if (msg->msg_name != NULL && hsock->peer_locator.ss_family == 0) {
220 memcpy(&hsock->peer_locator, msg->msg_name,
221 sizeof(hsock->peer_locator));
222 }
223 if (ctx != NULL) {
224 if (getsockname(hsock->sock_fd, (struct sockaddr *) &our_locator,
225 &sslen) < 0) {
226 HIP_PERROR("getsockname()");
227 return -1;
228 }
229 build_packet_context(ctx, (struct sockaddr *) &our_locator,
230 (struct sockaddr *) &hsock->peer_locator);
231 }
232 }
233
234 char *buf = (char *) msg->msg_iov->iov_base;
235 if (hipl_is_control_msg(buf, ret, hsock)) {
236 memmove(buf, buf + HIP_UDP_ZERO_BYTES_LEN,
237 HIP_MAX_PACKET - HIP_UDP_ZERO_BYTES_LEN);
238 ret -= HIP_UDP_ZERO_BYTES_LEN;
239 *is_user_msg = false;
240 }
241
242 return ret;
243}
244
245static int nonb_result_check(const int ret, const int err)
246{
247 if (ret < 0 && err != EWOULDBLOCK && err != EAGAIN) {
248 HIP_ERROR("BEX failed, errno = %d, errstr = %s\n", err,
249 strerror(err));
250 return -1;
251 }
252 if (ret < 0 && (err == EWOULDBLOCK || err == EAGAIN)) {
253 HIP_DEBUG("BEX returns EWOULDBLOCK or EAGAIN\n");
254 return -EWAITBEX;
255 }
256
257 return 0;
258}
259
260/**
261 * Wait for a HIP I1 packet and continue performing base exchange.
262 *
263 * @param hsock the libhipl socket waiting for the I1 packet.
264 * @param ctx the HIP packet context for HIP packet processing.
265 * @return 0 on success, -1 on error, -EWAITBEX when BEX is pending
266 */
267static int nonb_await_bex(struct hipl_sock *const hsock,
268 struct hip_packet_context *const ctx)
269{
270 struct msghdr params = { 0 };
271 struct iovec iov;
272 struct sockaddr_storage ss;
273 bool is_user_msg;
274 int ret = 0;
275 int flag;
276
277 params.msg_name = &ss;
278 params.msg_namelen = sizeof(ss);
279 params.msg_iovlen = 1;
280 iov.iov_base = ctx->input_msg;
281 iov.iov_len = HIP_MAX_PACKET;
282 params.msg_iov = &iov;
283
284 flag = fcntl(hsock->sock_fd, F_GETFL, 0);
285 fcntl(hsock->sock_fd, F_SETFL, flag | O_NONBLOCK);
286
287 set_hip_connection_parameters(hsock->sock_fd, hsock->src_port, 0);
288 ret = recv_msg_wrapper(hsock, &params, 0, ctx, &is_user_msg);
289 if ((ret = nonb_result_check(ret, errno)) != 0) {
290 HIP_DEBUG("returns %d\n", ret);
291 goto out;
292 }
293
294 if (is_user_msg || hip_receive_control_packet(ctx) < 0) {
295 HIP_ERROR("hip_receive_control_packet() failed\n");
296 ret = -1;
297 }
298
299out:
300 fcntl(hsock->sock_fd, F_SETFL, flag);
301 return ret;
302}
303
304/**
305 * Trigger BEX in a non-blocking way.
306 *
307 * @param hsock the libhipl socket to trigger BEX.
308 * @param src_hit the source HIT for base exchange.
309 * @param dst_hit the destination HIT for base exchange.
310 * @param dst_port the destination port.
311 * @return -1 on error, -EWAITBEX when the BEX is pending, 0 if sending
312 * BEX trigger message successfully.
313 */
314static int nonb_trigger_bex(struct hipl_sock *hsock, const hip_hit_t *src_hit,
315 const hip_hit_t *dst_hit, const int dst_port)
316{
317 struct in6_addr dst_addr;
318 int err = 0, flag;
319
320 flag = fcntl(hsock->sock_fd, F_GETFL, 0);
321 fcntl(hsock->sock_fd, F_SETFL, flag | O_NONBLOCK);
322
323 err = hip_map_id_to_addr(dst_hit, NULL, &dst_addr);
324 HIP_IFEL(err < 0, -1, "failed to match hit to IP\n");
325 HIP_IFEL(ipv6_addr_any(&dst_addr), -1, "Couldn't map HIT to IP\n");
326
327 set_hip_connection_parameters(hsock->sock_fd, hsock->src_port, dst_port);
328 err = netdev_trigger_bex(src_hit, dst_hit, NULL, NULL, NULL, &dst_addr);
329 HIP_DEBUG("netdev_trigger_bex returns %d, errno = %d\n", err, errno);
330 err = nonb_result_check(err, errno);
331 if (err == 0) {
332 hsock->ha = hip_hadb_find_byhits(src_hit, dst_hit);
333 }
334
335out_err:
336 fcntl(hsock->sock_fd, F_SETFL, flag);
337 return err;
338}
339
340/**
341 * Handle BEX for a libhipl socket.
342 *
343 * If param @c peer_hit is given, current libhipl socket will be the initiator
344 * and trigger the BEX. otherwise, it acts as a responder and waits for an I1
345 * message.
346 *
347 * @param hsock the libhipl socket to handle BEX.
348 * @param peer_hit the peer's hit and port.
349 * @return -1 on error, -EWAITBEX when the BEX is pending, and
350 * -EBEXESTABLISHED when BEX finishes.
351 */
352static int handle_bex(struct hipl_sock *hsock, struct sockaddr_in6 *peer_hit)
353{
354 int err = 0;
355 struct hip_packet_context ctx = { 0 };
356
357 // We are the initiator, send I1
358 if (hipl_hsock_ha_state(hsock) == HIP_STATE_UNASSOCIATED && peer_hit) {
359 hsock->peer_hit = peer_hit->sin6_addr;
360
361 err = nonb_trigger_bex(hsock, &hsock->src_hit, &peer_hit->sin6_addr,
362 ntohs(peer_hit->sin6_port));
363 // send I1 successfully, return -EWAITBEX.
364 if (err == 0) {
365 err = -EWAITBEX;
366 }
367 return err;
368 }
369
370 // waiting for and handle control messages
371 hsock->ha = hip_hadb_find_byhits(&hsock->src_hit, &hsock->peer_hit);
372 if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) {
373 ctx.input_msg = hip_msg_alloc();
374 ctx.output_msg = hip_msg_alloc();
375 HIP_IFEL(!ctx.input_msg || !ctx.output_msg, -ENOMEM,
376 "hip_msg_alloc() failed\n");
377
378 err = nonb_await_bex(hsock, &ctx);
379 HIP_DEBUG("nonb_await_bex returns %d\n", err);
380 if (err < 0) { /* -1 or -EWAITBEX */
381 goto out_err;
382 }
383 hsock->peer_hit = ctx.input_msg->hit_sender;
384 hsock->ha = hip_hadb_find_byhits(&hsock->src_hit, &hsock->peer_hit);
385 }
386
387 if (hipl_hsock_ha_state(hsock) == HIP_STATE_ESTABLISHED) {
388 err = -EBEXESTABLISHED;
389 } else {
390 err = -EWAITBEX;
391 }
392
393out_err:
394 free(ctx.input_msg);
395 free(ctx.output_msg);
396 return err;
397}
398
399static int validate_udp_peer_addr(const struct hipl_sock *const hsock,
400 const struct sockaddr_storage *const saddr)
401{
402 const struct in6_addr *paddr;
403 struct in6_addr peer_addr;
404
405 if (hsock->sock_proto != IPPROTO_UDP) {
406 return 0;
407 }
408
409 switch (saddr->ss_family) {
410 case AF_INET:
411 IPV4_TO_IPV6_MAP(&((const struct sockaddr_in *) saddr)->sin_addr,
412 &peer_addr);
413 paddr = &peer_addr;
414 break;
415
416 case AF_INET6:
417 paddr = &((const struct sockaddr_in6 *) saddr)->sin6_addr;
418 break;
419
420 default:
421 HIP_DEBUG("Unsupported family: %d\n", saddr->ss_family);
422 return -1;
423 }
424
425 if (ipv6_addr_cmp(&hsock->ha->peer_addr, paddr)) {
426 HIP_DEBUG("Packet not from associated address. Dropping.\n");
427 HIP_DEBUG_IN6ADDR("expected", &hsock->ha->peer_addr);
428 HIP_DEBUG_IN6ADDR("got", paddr);
429 return -1;
430 }
431
432 return 0;
433}
434
435/**
436 * Build a @c sockaddr_storage from a given IPv6 address and a port number.
437 *
438 * If the address is V4MAPPED, the storage family will be @c AF_INET,
439 * otherwise the storage family will be @c AF_INET6.
440 *
441 * @param addr a V6 address or a V4MAPPED address.
442 * @param port the port number.
443 * @param ss the @c sockaddr_storage to be filled.
444 */
445void hipl_build_addrstorage(const struct in6_addr *const addr,
446 const uint16_t port,
447 struct sockaddr_storage *const ss)
448{
449 HIP_ASSERT(addr && ss);
450 memset(ss, 0, sizeof(*ss));
451
452 if (IN6_IS_ADDR_V4MAPPED(addr)) {
453 struct sockaddr_in *const in = (struct sockaddr_in *) ss;
454 in->sin_family = AF_INET;
455 IPV6_TO_IPV4_MAP(addr, &in->sin_addr);
456 in->sin_port = htons(port);
457 } else {
458 struct sockaddr_in6 *const in6 = (struct sockaddr_in6 *) ss;
459 in6->sin6_family = AF_INET6;
460 ipv6_addr_copy(&in6->sin6_addr, addr);
461 in6->sin6_port = htons(port);
462 }
463}
464
465/**
466 * Create a libhipl socket.
467 *
468 * @param family the communications domain of the libhipl socket
469 * @param type the socket type of the libhipl socket
470 * @param protocol the protocol of the libhipl socket
471 * @return the ID of the new libhipl socket on success, negative
472 * number otherwise
473 */
474int hipl_socket_internal(const int family, const int type, const int protocol)
475{
476 int sock;
477 int on = 1, off = 0;
478 struct hipl_sock *hsock = NULL;
479
480 //TODO support IPV6
481 if (family == AF_INET6) {
482 HIP_ERROR("No IPv6 support yet.\n");
483 return -ENOTSUP;
484 }
485
486 sock = socket(family, type, protocol);
487 if (family == AF_INET) {
488 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
489 setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
490 setsockopt(sock, IPPROTO_IP, IP_RECVERR, &off, sizeof(off));
491 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
492 } else {
493 setsockopt(sock, IPPROTO_IPV6, IPV6_RECVERR, &off, sizeof(off));
494 setsockopt(sock, IPPROTO_IPV6, IPV6_2292PKTINFO, &on, sizeof(on));
495 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
496 }
497 if ((hsock = hipl_hsock_new(family, type, protocol)) == NULL) {
498 HIP_ERROR("Failed to create libhipl socket.\n");
499 close(sock);
500 return -1;
501 }
502 hsock->sock_fd = sock;
503 hip_get_default_hit(&hsock->src_hit);
504
505 return hsock->sid;
506}
507
508/**
509 * Bind a libhipl socket to a local address.
510 *
511 * @param hsock the libhipl socket for address binding.
512 * @param address the IP address to be bound.
513 * @param address_len the length of the @c address.
514 * @return 0 on success, -1 on error.
515 */
516int hipl_bind_internal(struct hipl_sock *const hsock,
517 const struct sockaddr *const address,
518 const socklen_t address_len)
519{
520 struct sockaddr_storage laddr = { 0 };
521 socklen_t laddr_len = sizeof(laddr);
522 uint16_t request_port;
523
524 request_port = get_port_from_saddr(address);
525 if (bind(hsock->sock_fd, address, address_len) < 0) {
526 HIP_PERROR("bind error:");
527 return -1;
528 }
529
530 /* Ask OS for the assigned port number */
531 if (request_port == 0) {
532 if (0 > getsockname(hsock->sock_fd, (struct sockaddr *) &laddr,
533 &laddr_len)) {
534 HIP_PERROR("getsockname() error: ");
535 return -1;
536 }
537 request_port = get_port_from_saddr((struct sockaddr *) &laddr);
538 }
539
540 hsock->src_port = ntohs(request_port);
541 HIP_DEBUG("bind to port %d\n", hsock->src_port);
542
543 return 0;
544}
545
546/**
547 * Initiate a connection to a peer.
548 *
549 * @param hsock the libhipl socket to initiate the connection.
550 * @param peer the peer's HIT and port number.
551 * @return 0 on success, -1 on error.
552 */
553int hipl_connect_internal(struct hipl_sock *const hsock,
554 const struct sockaddr_in6 *const peer)
555{
556 struct in6_addr dst_addr = { { { 0 } } };
557 struct sockaddr_storage ss;
558
559 if (ipv6_addr_any(&peer->sin6_addr)) {
560 HIP_ERROR("Invalid argument: dst_hit.\n");
561 return -1;
562 }
563
564 if (hip_map_id_to_addr(&peer->sin6_addr, NULL, &dst_addr) < 0) {
565 return -1;
566 }
567 if (ipv6_addr_any(&dst_addr)) {
568 HIP_ERROR("Couldn't map HIT to IP\n");
569 return -1;
570 }
571
572 HIP_DEBUG_IN6ADDR("Dest locator is: ", &dst_addr);
573 HIP_DEBUG("Dest locator is V4MAPPED: %d\n", IN6_IS_ADDR_V4MAPPED(&dst_addr));
574 hipl_build_addrstorage(&dst_addr, ntohs(peer->sin6_port), &ss);
575
576 if (connect(hsock->sock_fd, (struct sockaddr *) &ss, sizeof(ss)) < 0) {
577 HIP_ERROR("connect(): %s\n", strerror(errno));
578 return -1;
579 }
580
581 /* Save related information into hsock */
582 hsock->peer_hit = peer->sin6_addr;
583 hsock->peer_locator = ss;
584 if (hsock->src_port == 0) {
585 socklen_t taddr_len = sizeof(ss);
586
587 if (getsockname(hsock->sock_fd, (struct sockaddr *) &ss,
588 &taddr_len) < 0) {
589 HIP_PERROR("getsockname() error: ");
590 return -1;
591 }
592 hsock->src_port = ntohs(get_port_from_saddr((struct sockaddr *) &ss));
593 }
594
595 return 0;
596}
597
598/**
599 * Wait for an incoming connection on a libhipl socket.
600 *
601 * @param hsock the libhipl socket waiting for the connection.
602 * @return the ID of the accepted libhipl socket on success, -1 on error.
603 */
604int hipl_accept_internal(struct hipl_sock *const hsock)
605{
606 int new_fd;
607 struct hipl_sock *hsock_new = NULL;
608 struct sockaddr_storage ss = { 0 };
609 socklen_t ss_len = sizeof(ss);
610
611 new_fd = accept(hsock->sock_fd, (struct sockaddr *) &ss, &ss_len);
612 if (new_fd < 0) {
613 HIP_PERROR("accept(): ");
614 return -1;
615 }
616
617 hsock_new = hipl_hsock_new(hsock->sock_family, hsock->sock_type,
618 hsock->sock_proto);
619 hsock_new->src_port = hsock->src_port;
620 hsock_new->src_hit = hsock->src_hit;
621 hsock_new->sock_fd = new_fd;
622 hsock_new->peer_locator = ss;
623
624 return hsock_new->sid;
625}
626
627/**
628 * Receive data from a remote peer.
629 *
630 * Wait for base exchange if no host association exists.
631 * @note Data is currently sent unencrypted.
632 * @note Scatter read is not supported yet.
633 *
634 * @param hsock the libhipl socket for receiving data.
635 * @param msg the buffer to hold data and peer information.
636 * @param flags the flags of the socket function @c recvmsg().
637 * @return number of bytes received on success,
638 * 0 on end-of-file,
639 * -EWAITBEX when the BEX is pending,
640 * -EBEXESTABLISHED when BEX finishes,
641 * other negative numbers on error.
642 */
643ssize_t hipl_recvmsg_internal(struct hipl_sock *const hsock,
644 struct msghdr *const msg,
645 const int flags)
646{
647 struct hip_packet_context ctx = { 0 };
648 struct msghdr params = { 0 };
649 struct iovec iov;
650 struct sockaddr_storage recv_remote_addr;
651 int err = 0;
652 bool is_user_msg;
653
654 if (msg->msg_iovlen != 1) {
655 HIP_ERROR("Invalid iovlen: %d, scatter read is not supported yet\n",
656 msg->msg_iovlen);
657 return -ENOTSUP;
658 }
659
660 /* Bind to an ephemeral port if the src port hasn't been bound yet */
661 if (auto_bind(hsock)) {
662 HIP_ERROR("Fail to bind the hip socket.\n");
663 return -1;
664 }
665
666 /* Handle BEX if HA hasn't established */
667 if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED
668 && hipl_hsock_ha_state(hsock) != HIP_STATE_CLOSING) {
669 return handle_bex(hsock, NULL);
670 }
671
672 ctx.input_msg = hip_msg_alloc();
673 ctx.output_msg = hip_msg_alloc();
674 HIP_IFEL(!ctx.input_msg || !ctx.output_msg, -ENOMEM,
675 "hip_msg_alloc() failed\n");
676 params.msg_name = &recv_remote_addr;
677 params.msg_namelen = sizeof(recv_remote_addr);
678 params.msg_iovlen = 1;
679 iov.iov_base = ctx.input_msg;
680 iov.iov_len = HIP_MAX_PACKET;
681 params.msg_iov = &iov;
682
683 err = recv_msg_wrapper(hsock, &params, flags, &ctx, &is_user_msg);
684 HIP_IFEL(err < 0, -1, "recv_msg_wrapper() failed\n");
685
686 if (validate_udp_peer_addr(hsock, &recv_remote_addr) < 0) {
687 HIP_IFEL(true, -EAGAIN,
688 "Received a packet with invalid peer address, dropping.\n");
689 }
690 if (!is_user_msg) {
691 HIP_DEBUG("receive a hip control message.\n");
692 hip_receive_control_packet(&ctx);
693 if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) {
694 HIP_DEBUG("HA state change to %d, return 0.\n", hsock->ha->state);
695 return 0;
696 }
697 } else {
698 HIP_DEBUG("receive a user message.\n");
699 // TODO, if buffer size is too small, we should save it to a internal buffer
700 // and only return content with length specified by user's buffer (TCP).
701 // return error for UDP in this case.
702 struct iovec *iovp;
703 struct sockaddr_in6 *hitp;
704 hitp = msg->msg_name;
705 iovp = msg->msg_iov;
706 HIP_IFEL(iovp->iov_len < (unsigned int) err, -1,
707 "buffer size too small\n");
708 HIP_DEBUG_HIT("ha->hit_peer:", &hsock->ha->hit_peer);
709 hitp->sin6_family = AF_INET6;
710 hitp->sin6_port = get_port_from_saddr((const struct sockaddr *) &hsock->peer_locator);
711 HIP_DEBUG("hitp port: %d\n", ntohs(hitp->sin6_port));
712 hitp->sin6_addr = hsock->ha->hit_peer;
713 memcpy(iovp->iov_base, ctx.input_msg, err);
714 }
715
716out_err:
717 free(ctx.input_msg);
718 free(ctx.output_msg);
719 return err;
720}
721
722/**
723 * Send data to a peer.
724 *
725 * Trigger base exchange if no host association exists.
726 * @note Data is currently sent unencrypted.
727 * @note Gather write is not supported yet.
728 *
729 * @param hsock the libhipl socket for sending data.
730 * @param msg containing data, and peer information.
731 * @param flags the flags of the socket function @c sendmsg().
732 * @return number of bytes sent on success,
733 * -EWAITBEX if the BEX is pending,
734 * -EBEXESTABLISHED if the BEX finishes,
735 * other negative number on error.
736 */
737ssize_t hipl_sendmsg_internal(struct hipl_sock *const hsock,
738 struct msghdr *const msg,
739 const int flags)
740{
741 int fd = hsock->sock_fd;
742
743 /* Gather write is not supported yet */
744 if (msg->msg_iovlen > 1) {
745 HIP_ERROR("Invalid iovlen: %d, gather write is not supported\n",
746 msg->msg_iovlen);
747 return -ENOTSUP;
748 }
749
750 /* Bind to an ephemeral port if the src port hasn't been bound yet */
751 if (auto_bind(hsock)) {
752 HIP_ERROR("Fail to bind the hip socket.\n");
753 return -1;
754 }
755
756 /* Start BEX if HA hasn't established */
757 if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) {
758 return handle_bex(hsock, msg->msg_name);
759 }
760
761 /* Determine peer's locator and send out the message */
762 HIP_DEBUG("BEX ok, start to send user data\n");
763 if (hsock->peer_locator.ss_family == 0) {
764 hipl_build_addrstorage(&hsock->ha->peer_addr,
765 hsock->ha->peer_udp_port,
766 &hsock->peer_locator);
767 }
768 msg->msg_namelen = sizeof(hsock->peer_locator);
769 memcpy(msg->msg_name, &hsock->peer_locator, msg->msg_namelen);
770 return sendmsg(fd, msg, flags);
771}
0772
=== added file 'lib/hipl/lhipl_operations.h'
--- lib/hipl/lhipl_operations.h 1970-01-01 00:00:00 +0000
+++ lib/hipl/lhipl_operations.h 2012-04-17 15:16:21 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef HIPL_LIB_HIPL_LHIPL_OPERATIONS_H
27#define HIPL_LIB_HIPL_LHIPL_OPERATIONS_H
28
29#include "lib/hipl/lhipl_sock.h"
30
31
32int hipl_socket_internal(const int family, const int type, const int protocol);
33
34int hipl_bind_internal(struct hipl_sock *const hsock,
35 const struct sockaddr *const address,
36 const socklen_t address_len);
37
38int hipl_connect_internal(struct hipl_sock *const hsock,
39 const struct sockaddr_in6 *const addr);
40
41int hipl_accept_internal(struct hipl_sock *const hsock);
42
43ssize_t hipl_recvmsg_internal(struct hipl_sock *const hsock,
44 struct msghdr *const msg,
45 const int flags);
46
47ssize_t hipl_sendmsg_internal(struct hipl_sock *const hsock,
48 struct msghdr *const msg,
49 const int flags);
50
51void hipl_build_addrstorage(const struct in6_addr *const addr,
52 const uint16_t port,
53 struct sockaddr_storage *const ss);
54
55#endif /* HIPL_LIB_HIPL_LHIPL_OPERATIONS_H */
056
=== added file 'lib/hipl/lhipl_sock.c'
--- lib/hipl/lhipl_sock.c 1970-01-01 00:00:00 +0000
+++ lib/hipl/lhipl_sock.c 2012-04-17 15:16:21 +0000
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) 2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file contains functions for maintaining libhipl sockets.
29 */
30
31#define _BSD_SOURCE
32
33#include <sys/socket.h>
34#include <string.h>
35#include <unistd.h>
36
37#include "lib/core/debug.h"
38#include "lib/core/hashtable.h"
39#include "lhipl_sock.h"
40
41
42/* A hashtable to record all opening libhipl sockets */
43static HIP_HASHTABLE *hsocks = NULL;
44
45static unsigned long hipl_sk_hash(const struct hipl_sock *hsock)
46{
47 return hsock->sid;
48}
49
50STATIC_IMPLEMENT_LHASH_HASH_FN(hipl_sk, struct hipl_sock)
51
52static int hipl_sk_cmp(const struct hipl_sock *hsock1,
53 const struct hipl_sock *hsock2)
54{
55 return memcmp(&hsock1->sid, &hsock2->sid, sizeof(hsock1->sid));
56}
57
58STATIC_IMPLEMENT_LHASH_COMP_FN(hipl_sk, struct hipl_sock)
59
60static uint32_t hsock_generate_id(void)
61{
62 static uint32_t id_generator = HIPL_LIB_HSOCK_ID_MIN;
63
64 if (id_generator == HIPL_LIB_HSOCK_ID_MAX) {
65 id_generator = HIPL_LIB_HSOCK_ID_MIN;
66 } else {
67 id_generator += 1;
68 }
69
70 return id_generator;
71}
72
73/**
74 * Initialize the libhipl socket hashtable.
75 */
76void hipl_hsock_init(void)
77{
78 hsocks = hip_ht_init(LHASH_HASH_FN(hipl_sk), LHASH_COMP_FN(hipl_sk));
79}
80
81/**
82 * Create a new libhipl socket and save it to the libhipl socket hashtable.
83 *
84 * @param family the address family of the libhipl socket (INET or INET6).
85 * @param type the type of the protocol.
86 * @param protocol the protocol of the libhipl socket (TCP or UDP).
87 * @return pointer to the created libhipl socket on success, NULL on
88 * error.
89 */
90struct hipl_sock *hipl_hsock_new(const int family, const int type,
91 const int protocol)
92{
93 struct hipl_sock *hsock = NULL;
94
95 hsock = calloc(sizeof(struct hipl_sock), sizeof(uint8_t));
96 if (hsock == NULL) {
97 HIP_ERROR("calloc() failed.\n");
98 return NULL;
99 }
100
101 hsock->sid = hsock_generate_id();
102 hsock->sock_family = family;
103 hsock->sock_type = type;
104 hsock->sock_proto = protocol;
105 hip_ht_add(hsocks, hsock);
106 return hsock;
107}
108
109/**
110 * Get a libhipl socket by its ID.
111 *
112 * @param hsock_id the ID of the libhipl socket.
113 * @return pointer to the libhipl socket on success, or NULL if the
114 * given ID doesn't match any record.
115 */
116struct hipl_sock *hipl_hsock_find(const uint16_t hsock_id)
117{
118 struct hipl_sock hsock;
119
120 hsock.sid = hsock_id;
121 return hip_ht_find(hsocks, &hsock);
122}
123
124/**
125 * Delete a libhipl socket and free the memory it occupies.
126 *
127 * @param hsock pointer to the libhipl socket to be deleted.
128 */
129void hipl_hsock_delete_and_free(struct hipl_sock *const hsock)
130{
131 struct hipl_sock *deleted_item;
132
133 deleted_item = hip_ht_delete(hsocks, hsock);
134 free(deleted_item);
135}
136
137/**
138 * Get the HIP association state of a given libhipl socket.
139 *
140 * @param hsock the libhipl socket.
141 * @return the HIP association state of the libhipl socket.
142 */
143enum hip_state hipl_hsock_ha_state(const struct hipl_sock *const hsock)
144{
145 if (!hsock->ha) {
146 return HIP_STATE_UNASSOCIATED;
147 } else {
148 return hsock->ha->state;
149 }
150}
0151
=== added file 'lib/hipl/lhipl_sock.h'
--- lib/hipl/lhipl_sock.h 1970-01-01 00:00:00 +0000
+++ lib/hipl/lhipl_sock.h 2012-04-17 15:16:21 +0000
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef HIPL_LIB_HIPL_LHIPL_SOCK_H
27#define HIPL_LIB_HIPL_LHIPL_SOCK_H
28
29#include <limits.h>
30
31#include "lib/core/protodefs.h"
32#include "lib/core/state.h"
33
34
35#define HIPL_LIB_HSOCK_ID_MIN 1
36#define HIPL_LIB_HSOCK_ID_MAX USHRT_MAX
37#define HIPL_LIB_HSOCK_MAX 1024
38
39/* This struct contains internal information about each libhipl socket.
40 *
41 * It is generated when a new libhipl socket is created.
42 */
43struct hipl_sock {
44 uint16_t sid; /* libhipl socket ID */
45 struct hip_hadb_state *ha;
46 hip_hit_t peer_hit;
47 struct sockaddr_storage peer_locator;
48 hip_hit_t src_hit; /* our HIT */
49 int src_port; /* our port number */
50 int sock_fd; /* underlying socket */
51 int sock_family;
52 int sock_type;
53 int sock_proto;
54};
55
56void hipl_hsock_init(void);
57
58enum hip_state hipl_hsock_ha_state(const struct hipl_sock *const hsock);
59
60struct hipl_sock *hipl_hsock_new(const int family, const int type,
61 const int protocol);
62
63struct hipl_sock *hipl_hsock_find(const uint16_t hsock_id);
64
65void hipl_hsock_delete_and_free(struct hipl_sock *const hsock);
66
67#endif /* HIPL_LIB_HIPL_LHIPL_SOCK_H */
068
=== renamed file 'hipd/lsidb.c' => 'lib/hipl/lsidb.c'
=== renamed file 'hipd/lsidb.h' => 'lib/hipl/lsidb.h'
=== renamed file 'hipd/maintenance.c' => 'lib/hipl/maintenance.c'
=== renamed file 'hipd/maintenance.h' => 'lib/hipl/maintenance.h'
=== renamed file 'hipd/nat.c' => 'lib/hipl/nat.c'
=== renamed file 'hipd/nat.h' => 'lib/hipl/nat.h'
=== renamed file 'hipd/netdev.c' => 'lib/hipl/netdev.c'
=== renamed file 'hipd/netdev.h' => 'lib/hipl/netdev.h'
=== renamed file 'hipd/nsupdate.c' => 'lib/hipl/nsupdate.c'
=== renamed file 'hipd/nsupdate.h' => 'lib/hipl/nsupdate.h'
=== renamed file 'hipd/opp_mode.c' => 'lib/hipl/opp_mode.c'
=== renamed file 'hipd/opp_mode.h' => 'lib/hipl/opp_mode.h'
=== renamed file 'hipd/output.c' => 'lib/hipl/output.c'
--- hipd/output.c 2012-04-16 14:47:42 +0000
+++ lib/hipl/output.c 2012-04-17 15:16:21 +0000
@@ -848,7 +848,8 @@
848 HIP_ASSERT(!hit_is_opportunistic_hit(&ctx->input_msg->hit_receiver));848 HIP_ASSERT(!hit_is_opportunistic_hit(&ctx->input_msg->hit_receiver));
849849
850 /* Case: I ----->IPv4---> RVS ---IPv6---> R */850 /* Case: I ----->IPv4---> RVS ---IPv6---> R */
851 if (IN6_IS_ADDR_V4MAPPED(r1_src_addr) !=851 if (!hipl_is_libhip_mode() &&
852 IN6_IS_ADDR_V4MAPPED(r1_src_addr) !=
852 IN6_IS_ADDR_V4MAPPED(r1_dst_addr)) {853 IN6_IS_ADDR_V4MAPPED(r1_dst_addr)) {
853 HIP_DEBUG_IN6ADDR("r1_src_addr", r1_src_addr);854 HIP_DEBUG_IN6ADDR("r1_src_addr", r1_src_addr);
854 HIP_DEBUG_IN6ADDR("r1_dst_addr", r1_dst_addr);855 HIP_DEBUG_IN6ADDR("r1_dst_addr", r1_dst_addr);
@@ -1217,6 +1218,9 @@
1217 goto out_err;1218 goto out_err;
1218 }1219 }
12191220
1221 if (hipl_is_libhip_mode()) {
1222 udp = 1;
1223 }
1220 dst_is_ipv4 = IN6_IS_ADDR_V4MAPPED(peer_addr);1224 dst_is_ipv4 = IN6_IS_ADDR_V4MAPPED(peer_addr);
1221 len = hip_get_msg_total_len(msg);1225 len = hip_get_msg_total_len(msg);
12221226
@@ -1245,13 +1249,16 @@
1245 if (local_addr) {1249 if (local_addr) {
1246 HIP_DEBUG("local address given\n");1250 HIP_DEBUG("local address given\n");
1247 memcpy(&my_addr, local_addr, sizeof(struct in6_addr));1251 memcpy(&my_addr, local_addr, sizeof(struct in6_addr));
1248 } else {1252 } else if (!hipl_is_libhip_mode()) {
1249 HIP_DEBUG("no local address, selecting one\n");1253 HIP_DEBUG("no local address, selecting one\n");
1250 HIP_IFEL(hip_select_source_address(&my_addr, peer_addr), -1,1254 HIP_IFEL(hip_select_source_address(&my_addr, peer_addr), -1,
1251 "Cannot find source address\n");1255 "Cannot find source address\n");
1256 } else {
1257 memset(&my_addr, 0, sizeof(my_addr));
1252 }1258 }
12531259
1254 src_is_ipv4 = IN6_IS_ADDR_V4MAPPED(&my_addr);1260 src_is_ipv4 = IN6_IS_ADDR_V4MAPPED(&my_addr) ||
1261 (dst_is_ipv4 && ipv6_addr_any(&my_addr));
12551262
1256 if (src_is_ipv4) {1263 if (src_is_ipv4) {
1257 IPV6_TO_IPV4_MAP(&my_addr, &src4->sin_addr);1264 IPV6_TO_IPV4_MAP(&my_addr, &src4->sin_addr);
@@ -1305,9 +1312,10 @@
13051312
1306 /* Handover may cause e.g. on-link duplicate address detection1313 /* Handover may cause e.g. on-link duplicate address detection
1307 * which may cause bind to fail. */1314 * which may cause bind to fail. */
13081315 if (!hipl_is_libhip_mode()) {
1309 HIP_IFEL(bind(hip_raw_sock_output, (struct sockaddr *) &src, sa_size),1316 HIP_IFEL(bind(hip_raw_sock_output, (struct sockaddr *) &src, sa_size),
1310 -1, "Binding to raw sock failed\n");1317 -1, "Binding to raw sock failed\n");
1318 }
13111319
1312#if (HIP_SIMULATE_PACKET_LOSS_PROBABILITY > 0)1320#if (HIP_SIMULATE_PACKET_LOSS_PROBABILITY > 0)
1313 if (HIP_SIMULATE_PACKET_LOSS && HIP_SIMULATE_PACKET_IS_LOST()) {1321 if (HIP_SIMULATE_PACKET_LOSS && HIP_SIMULATE_PACKET_IS_LOST()) {
@@ -1324,18 +1332,25 @@
1324 len = hip_get_msg_total_len(msg);1332 len = hip_get_msg_total_len(msg);
13251333
1326 if (udp) {1334 if (udp) {
1327 struct udphdr *uh = (struct udphdr *) msg;1335 if (!hipl_is_libhip_mode()) {
13281336 /* Insert 32 bits of zero bytes between UDP and HIP */
1329 /* Insert 32 bits of zero bytes between UDP and HIP */1337 memmove((char *) msg + HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr), msg, len);
1330 memmove((char *) msg + HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr), msg, len);1338 memset(msg, 0, HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr));
1331 memset(msg, 0, HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr));1339 len += HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr);
1332 len += HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr);1340
13331341 struct udphdr *uh = (struct udphdr *) msg;
1334 uh->source = htons(src_port);1342 uh->source = htons(src_port);
1335 uh->dest = htons(dst_port);1343 uh->dest = htons(dst_port);
1336 uh->len = htons(len);1344 uh->len = htons(len);
1337 uh->check = 0;1345 uh->check = 0;
1338 memmoved = 1;1346 } else {
1347 memmove((char *) msg + HIP_UDP_ZERO_BYTES_LEN, msg, len);
1348 memset(msg, 0, HIP_UDP_ZERO_BYTES_LEN);
1349 len += HIP_UDP_ZERO_BYTES_LEN;
1350
1351 dst4->sin_port = htons(dst_port);
1352 }
1353 memmoved = 1;
1339 }1354 }
13401355
1341 sent = sendto(hip_raw_sock_output, msg, len, 0,1356 sent = sendto(hip_raw_sock_output, msg, len, 0,
13421357
=== renamed file 'hipd/output.h' => 'lib/hipl/output.h'
=== renamed file 'hipd/pkt_handling.c' => 'lib/hipl/pkt_handling.c'
=== renamed file 'hipd/pkt_handling.h' => 'lib/hipl/pkt_handling.h'
=== renamed file 'hipd/registration.c' => 'lib/hipl/registration.c'
=== renamed file 'hipd/registration.h' => 'lib/hipl/registration.h'
=== renamed file 'hipd/user.c' => 'lib/hipl/user.c'
=== renamed file 'hipd/user.h' => 'lib/hipl/user.h'
=== renamed file 'hipd/user_ipsec_hipd_msg.c' => 'lib/hipl/user_ipsec_hipd_msg.c'
=== renamed file 'hipd/user_ipsec_hipd_msg.h' => 'lib/hipl/user_ipsec_hipd_msg.h'
=== renamed file 'hipd/user_ipsec_sadb_api.c' => 'lib/hipl/user_ipsec_sadb_api.c'
=== renamed file 'hipd/user_ipsec_sadb_api.h' => 'lib/hipl/user_ipsec_sadb_api.h'
=== modified file 'modules/cert/hipd/cert.c'
--- modules/cert/hipd/cert.c 2012-03-08 09:38:56 +0000
+++ modules/cert/hipd/cert.c 2012-04-17 15:16:21 +0000
@@ -33,13 +33,13 @@
33#include <stdlib.h>33#include <stdlib.h>
34#include <string.h>34#include <string.h>
3535
36#include "hipd/hipd.h"
37#include "hipd/pkt_handling.h"
38#include "lib/core/builder.h"36#include "lib/core/builder.h"
39#include "lib/core/cert.h"37#include "lib/core/cert.h"
40#include "lib/core/debug.h"38#include "lib/core/debug.h"
41#include "lib/core/ife.h"39#include "lib/core/ife.h"
42#include "lib/core/protodefs.h"40#include "lib/core/protodefs.h"
41#include "lib/hipl/hipd.h"
42#include "lib/hipl/pkt_handling.h"
43#include "modules/midauth/hipd/midauth.h"43#include "modules/midauth/hipd/midauth.h"
44#include "modules/update/hipd/update.h"44#include "modules/update/hipd/update.h"
45#include "cert.h"45#include "cert.h"
4646
=== modified file 'modules/heartbeat/hipd/heartbeat.c'
--- modules/heartbeat/hipd/heartbeat.c 2012-03-21 13:14:54 +0000
+++ modules/heartbeat/hipd/heartbeat.c 2012-04-17 15:16:21 +0000
@@ -65,15 +65,6 @@
65#include <sys/types.h>65#include <sys/types.h>
66#include <sys/socket.h>66#include <sys/socket.h>
6767
68#include "hipd/close.h"
69#include "hipd/hadb.h"
70#include "hipd/init.h"
71#include "hipd/hip_socket.h"
72#include "hipd/maintenance.h"
73#include "hipd/nat.h"
74#include "hipd/output.h"
75#include "hipd/pkt_handling.h"
76#include "hipd/user.h"
77#include "lib/core/common.h"68#include "lib/core/common.h"
78#include "lib/core/debug.h"69#include "lib/core/debug.h"
79#include "lib/core/icomm.h"70#include "lib/core/icomm.h"
@@ -84,6 +75,15 @@
84#include "lib/core/straddr.h"75#include "lib/core/straddr.h"
85#include "lib/core/modularization.h"76#include "lib/core/modularization.h"
86#include "lib/core/gpl/nlink.h"77#include "lib/core/gpl/nlink.h"
78#include "lib/hipl/close.h"
79#include "lib/hipl/hadb.h"
80#include "lib/hipl/hip_socket.h"
81#include "lib/hipl/init.h"
82#include "lib/hipl/maintenance.h"
83#include "lib/hipl/nat.h"
84#include "lib/hipl/output.h"
85#include "lib/hipl/pkt_handling.h"
86#include "lib/hipl/user.h"
87#include "heartbeat.h"87#include "heartbeat.h"
8888
89#define HIP_MAX_ICMP_PACKET 51289#define HIP_MAX_ICMP_PACKET 512
9090
=== modified file 'modules/heartbeat_update/hipd/hb_update.c'
--- modules/heartbeat_update/hipd/hb_update.c 2012-03-21 13:14:54 +0000
+++ modules/heartbeat_update/hipd/hb_update.c 2012-04-17 15:16:21 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.2 * Copyright (c) 2010, 2012 Aalto University and RWTH Aachen University.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation5 * obtaining a copy of this software and associated documentation
@@ -40,12 +40,12 @@
40#include <stdint.h>40#include <stdint.h>
41#include <stdlib.h>41#include <stdlib.h>
4242
43#include "hipd/hadb.h"
44#include "hipd/maintenance.h"
45#include "lib/core/builder.h"43#include "lib/core/builder.h"
46#include "lib/core/common.h"44#include "lib/core/common.h"
47#include "lib/core/debug.h"45#include "lib/core/debug.h"
48#include "lib/core/protodefs.h"46#include "lib/core/protodefs.h"
47#include "lib/hipl/hadb.h"
48#include "lib/hipl/maintenance.h"
49#include "modules/update/hipd/update.h"49#include "modules/update/hipd/update.h"
50#include "modules/update/hipd/update_locator.h"50#include "modules/update/hipd/update_locator.h"
51#include "hb_update.h"51#include "hb_update.h"
5252
=== modified file 'modules/midauth/hipd/midauth.c'
--- modules/midauth/hipd/midauth.c 2012-04-17 11:20:20 +0000
+++ modules/midauth/hipd/midauth.c 2012-04-17 15:16:21 +0000
@@ -33,8 +33,6 @@
33#include <stdint.h>33#include <stdint.h>
34#include <string.h>34#include <string.h>
3535
36#include "hipd/hidb.h"
37#include "hipd/pkt_handling.h"
38#include "lib/core/builder.h"36#include "lib/core/builder.h"
39#include "lib/core/common.h"37#include "lib/core/common.h"
40#include "lib/core/ife.h"38#include "lib/core/ife.h"
@@ -42,6 +40,8 @@
42#include "lib/core/protodefs.h"40#include "lib/core/protodefs.h"
43#include "lib/core/solve.h"41#include "lib/core/solve.h"
44#include "lib/core/state.h"42#include "lib/core/state.h"
43#include "lib/hipl/hidb.h"
44#include "lib/hipl/pkt_handling.h"
45#include "modules/midauth/lib/midauth_builder.h"45#include "modules/midauth/lib/midauth_builder.h"
46#include "modules/update/hipd/update.h"46#include "modules/update/hipd/update.h"
47#include "midauth.h"47#include "midauth.h"
4848
=== modified file 'modules/update/hipd/update.c'
--- modules/update/hipd/update.c 2012-03-20 12:52:49 +0000
+++ modules/update/hipd/update.c 2012-04-17 15:16:21 +0000
@@ -37,17 +37,6 @@
37#include <string.h>37#include <string.h>
3838
39#include "config.h"39#include "config.h"
40#include "hipd/cookie.h"
41#include "hipd/hadb.h"
42#include "hipd/hidb.h"
43#include "hipd/hipd.h"
44#include "hipd/input.h"
45#include "hipd/maintenance.h"
46#include "hipd/netdev.h"
47#include "hipd/nsupdate.h"
48#include "hipd/output.h"
49#include "hipd/pkt_handling.h"
50#include "hipd/user.h"
51#include "lib/core/builder.h"40#include "lib/core/builder.h"
52#include "lib/core/debug.h"41#include "lib/core/debug.h"
53#include "lib/core/hip_udp.h"42#include "lib/core/hip_udp.h"
@@ -57,6 +46,17 @@
57#include "lib/core/prefix.h"46#include "lib/core/prefix.h"
58#include "lib/core/state.h"47#include "lib/core/state.h"
59#include "lib/core/performance.h"48#include "lib/core/performance.h"
49#include "lib/hipl/cookie.h"
50#include "lib/hipl/hadb.h"
51#include "lib/hipl/hidb.h"
52#include "lib/hipl/hipd.h"
53#include "lib/hipl/input.h"
54#include "lib/hipl/maintenance.h"
55#include "lib/hipl/netdev.h"
56#include "lib/hipl/nsupdate.h"
57#include "lib/hipl/output.h"
58#include "lib/hipl/pkt_handling.h"
59#include "lib/hipl/user.h"
60#include "update_builder.h"60#include "update_builder.h"
61#include "update_locator.h"61#include "update_locator.h"
62#include "update_param_handling.h"62#include "update_param_handling.h"
6363
=== modified file 'modules/update/hipd/update_builder.c'
--- modules/update/hipd/update_builder.c 2012-04-17 11:20:20 +0000
+++ modules/update/hipd/update_builder.c 2012-04-17 15:16:21 +0000
@@ -34,12 +34,12 @@
34#include <string.h>34#include <string.h>
35#include <errno.h>35#include <errno.h>
3636
37#include "hipd/hadb.h"
38#include "hipd/netdev.h"
39#include "lib/core/builder.h"37#include "lib/core/builder.h"
40#include "lib/core/ife.h"38#include "lib/core/ife.h"
41#include "lib/core/list.h"39#include "lib/core/list.h"
42#include "lib/core/prefix.h"40#include "lib/core/prefix.h"
41#include "lib/hipl/hadb.h"
42#include "lib/hipl/netdev.h"
43#include "update_builder.h"43#include "update_builder.h"
4444
45enum hip_locator_traffic_type {45enum hip_locator_traffic_type {
4646
=== modified file 'modules/update/hipd/update_locator.c'
--- modules/update/hipd/update_locator.c 2011-12-12 14:18:05 +0000
+++ modules/update/hipd/update_locator.c 2012-04-17 15:16:21 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.2 * Copyright (c) 2010, 2012 Aalto University and RWTH Aachen University.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation5 * obtaining a copy of this software and associated documentation
@@ -34,11 +34,11 @@
34#include <string.h>34#include <string.h>
35#include <openssl/lhash.h>35#include <openssl/lhash.h>
3636
37#include "hipd/maintenance.h"
38#include "lib/core/builder.h"37#include "lib/core/builder.h"
39#include "lib/core/debug.h"38#include "lib/core/debug.h"
40#include "lib/core/ife.h"39#include "lib/core/ife.h"
41#include "lib/core/protodefs.h"40#include "lib/core/protodefs.h"
41#include "lib/hipl/maintenance.h"
42#include "update_builder.h"42#include "update_builder.h"
43#include "update.h"43#include "update.h"
44#include "update_locator.h"44#include "update_locator.h"
4545
=== added file 'test/check_libhipl.c'
--- test/check_libhipl.c 1970-01-01 00:00:00 +0000
+++ test/check_libhipl.c 2012-04-17 15:16:21 +0000
@@ -0,0 +1,216 @@
1/*
2 * Copyright (c) 2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * @brief Tests of libhipl on localhost (see doc/HACKING on unit tests).
29 */
30
31#include <arpa/inet.h>
32#include <check.h>
33#include <errno.h>
34#include <stdbool.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <sys/select.h>
38#include <unistd.h>
39
40#include "lib/hipl/hidb.h"
41#include "lib/hipl/lhipl.h"
42
43#ifndef max
44#define max(a, b) (((a) > (b)) ? (a) : (b))
45#endif
46
47#define LO_IP "127.0.0.1"
48#define TEST_MSG "Hello Sailor!"
49#define SEND_PORT 22345
50#define RECV_PORT 22300
51
52static struct in6_addr lo_hit;
53static char peername[HIPL_MAX_PEERNAME];
54static struct sockaddr_in send_addr;
55static struct sockaddr_in recv_addr;
56
57static int sender;
58static int receiver;
59
60static void test_libhipl_lo_init(int proto)
61{
62 if (hipl_lib_init_all(HIPL_LIB_LOG_NONE) < 0) {
63 fail("hipl_lib_init_all");
64 }
65
66 fail_if(hip_get_default_hit(&lo_hit) < 0, "Failed to load local hit");
67 inet_ntop(AF_INET6, &lo_hit, peername, HIPL_MAX_PEERNAME);
68 fail_if(hipl_add_peer_info(peername, LO_IP) < 0,
69 "Failed to insert peer info");
70
71 send_addr.sin_family = AF_INET;
72 inet_pton(AF_INET, LO_IP, &send_addr.sin_addr);
73 send_addr.sin_port = htons(SEND_PORT);
74 recv_addr.sin_family = AF_INET;
75 inet_pton(AF_INET, LO_IP, &recv_addr.sin_addr);
76 recv_addr.sin_port = htons(RECV_PORT);
77
78 if (proto == IPPROTO_TCP) {
79 sender = hipl_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
80 receiver = hipl_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
81 } else if (proto == IPPROTO_UDP) {
82 sender = hipl_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
83 receiver = hipl_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
84 }
85 fail_if(sender <= 0 || receiver <= 0);
86
87 if (hipl_bind(sender, (struct sockaddr *) &send_addr,
88 sizeof(send_addr)) < 0) {
89 fail("hipl_bind() for sender");
90 }
91 if (hipl_bind(receiver, (struct sockaddr *) &recv_addr,
92 sizeof(recv_addr)) < 0) {
93 fail("hipl_bind() for receiver");
94 }
95
96 hipl_lib_set_bex_feedback(true);
97}
98
99static void test_libhipl_lo_main_loop(int send_hid, int recv_hid)
100{
101 char peer[HIPL_MAX_PEERNAME];
102 uint16_t peer_port;
103 char buf[1024];
104 fd_set rset;
105 int ret = 0;
106 int maxfd = max(hipl_lib_get_sockfd(send_hid),
107 hipl_lib_get_sockfd(recv_hid));
108
109 //trigger BEX
110 ret = hipl_sendto(send_hid, TEST_MSG, strlen(TEST_MSG), 0,
111 peername, RECV_PORT);
112 fail_if(ret != -EWAITBEX);
113
114 while (1) {
115 FD_ZERO(&rset);
116 FD_SET(hipl_lib_get_sockfd(send_hid), &rset);
117 FD_SET(hipl_lib_get_sockfd(recv_hid), &rset);
118 fail_if(select(maxfd + 1, &rset, NULL, NULL, NULL) < 0);
119
120 if (FD_ISSET(hipl_lib_get_sockfd(recv_hid), &rset)) {
121 ret = hipl_recvfrom(recv_hid, buf, 1024, 0, peer, &peer_port);
122 fail_if(ret < 0 && ret != -EWAITBEX && ret != -EBEXESTABLISHED);
123 fail_if(ret > 0 && ret != strlen(TEST_MSG));
124
125 if (ret == strlen(TEST_MSG)) {
126 buf[ret] = '\0';
127 fail_if(strcmp(buf, TEST_MSG) != 0);
128 fail_if(strcmp(peername, peer) != 0);
129 fail_if(peer_port != SEND_PORT);
130 return;
131 }
132 }
133 if (FD_ISSET(hipl_lib_get_sockfd(send_hid), &rset)) {
134 ret = hipl_sendto(send_hid, TEST_MSG, strlen(TEST_MSG), 0,
135 peername, RECV_PORT);
136 fail_if(ret < 0 && ret != -EWAITBEX && ret != -EBEXESTABLISHED);
137 fail_if(ret > 0 && ret != strlen(TEST_MSG));
138 }
139 }
140}
141
142START_TEST(test_libhipl_lo_tcp)
143{
144 fd_set wset, rset;
145 int maxfd, recv_slave = 0;
146
147 test_libhipl_lo_init(IPPROTO_TCP);
148
149 // Setup TCP connection
150 maxfd = max(hipl_lib_get_sockfd(sender), hipl_lib_get_sockfd(receiver));
151 if (hipl_listen(receiver, 5) < 0) {
152 fail("hipl_listen()");
153 }
154 fail_if(hipl_lib_set_nonblock(sender, true) < 0);
155 fail_if(hipl_lib_set_nonblock(receiver, true) < 0);
156 hipl_accept(receiver);
157 hipl_connect(sender, peername, RECV_PORT);
158 while (recv_slave <= 0) {
159 FD_ZERO(&wset);
160 FD_ZERO(&rset);
161 FD_SET(hipl_lib_get_sockfd(sender), &wset);
162 FD_SET(hipl_lib_get_sockfd(receiver), &rset);
163 fail_if(select(maxfd + 1, &rset, &wset, NULL, NULL) < 0);
164 if (FD_ISSET(hipl_lib_get_sockfd(receiver), &rset)) {
165 if ((recv_slave = hipl_accept(receiver)) < 0) {
166 fail("hipl_accept(), %s", strerror(errno));
167 }
168 }
169 if (FD_ISSET(hipl_lib_get_sockfd(sender), &wset)) {
170 if (hipl_connect(sender, peername, RECV_PORT) < 0
171 && errno != EINPROGRESS && errno != EISCONN) {
172 fail("hipl_connect() %s", strerror(errno));
173 }
174 }
175 }
176 fail_if(hipl_connect(sender, peername, RECV_PORT) < 0 && errno != EISCONN);
177 fail_if(hipl_lib_set_nonblock(sender, false) < 0);
178
179 // Process base exchange and user data
180 test_libhipl_lo_main_loop(sender, recv_slave);
181}
182END_TEST
183
184START_TEST(test_libhipl_lo_udp)
185{
186 test_libhipl_lo_init(IPPROTO_UDP);
187 test_libhipl_lo_main_loop(sender, receiver);
188}
189END_TEST
190
191static Suite *hipnc_suite(void)
192{
193 Suite *s = suite_create("libhipl");
194
195 TCase *tc_libhipl_lo = tcase_create("libhipl_lo");
196 tcase_add_test(tc_libhipl_lo, test_libhipl_lo_udp);
197 tcase_add_test(tc_libhipl_lo, test_libhipl_lo_tcp);
198 suite_add_tcase(s, tc_libhipl_lo);
199
200 return s;
201}
202
203int main(void)
204{
205 int number_failed;
206 Suite *s = hipnc_suite();
207 SRunner *sr = srunner_create(NULL);
208
209 srunner_add_suite(sr, s);
210 srunner_run_all(sr, CK_NORMAL);
211
212 number_failed = srunner_ntests_failed(sr);
213 srunner_free(sr);
214
215 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
216}
0217
=== modified file 'test/hipd/lsidb.c'
--- test/hipd/lsidb.c 2012-01-18 21:09:47 +0000
+++ test/hipd/lsidb.c 2012-04-17 15:16:21 +0000
@@ -26,7 +26,7 @@
26#include <check.h>26#include <check.h>
27#include <stdlib.h>27#include <stdlib.h>
2828
29#include "hipd/lsidb.c"29#include "lib/hipl/lsidb.c"
30#include "test_suites.h"30#include "test_suites.h"
3131
32START_TEST(test_lsidb_allocate_lsi_valid)32START_TEST(test_lsidb_allocate_lsi_valid)

Subscribers

People subscribed via source and target branches

to all changes: