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 |
Related bugs: |
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.
Commit message
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
Christof Mroz (christof-mroz) wrote : Posted in a previous version of this proposal | # |
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-
> // 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) {
*storage = node->next;
// could return here for micro optimization
} else {
storage = &node->next;
}
}
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_
>> + strcpy(hi_file_dup, hi_file);
>> + if ((err = check_and_
>> + 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_
Related stack memory usages have been reverted to malloc.
Regarding to check_and_
because the parent directory (user's home folder) should exist.
Nice hints for linkedlist, it greatly shorten the lines of code :)
Xin
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_
>
> Regarding to check_and_
> because the parent directory (user's home folder) should exist.
What happens if it does not exist?
Diego
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_
>> Regarding to check_and_
>> 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
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.
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.
Stefan Götz (stefan.goetz-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
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_
> + 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_
easy to use.
> +{
> + struct hip_ll_node *curr;
> + struct hip_ll_node *tmp;
> +
> + /* match first list node */
> + if (linkedlist != NULL && linkedlist-
the check for linkedlist != NULL should also cover the second part of this
function. I'd suggest adding an assertion for it.
> + && linkedlist-
> + tmp = linkedlist->head;
> + linkedlist->head = tmp->next;
> + linkedlist-
> + if (free_element != NULL) {
> + free_element(
> + }
> + 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-
> + if (free_element != NULL) {
> + free_element(
> + }
> + free(curr);
> + return;
> + }
> + tmp = tmp->next;
> + }
> +}
Why not go with Christof's version? It looked much simpler to me.
> +void hip_ll_
> + 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_
const correctness
> +int hip_read_
const correctness
> --- h...
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_
> 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-
>
> 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.
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-
>>
>> 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;
out_err:
free(mem);
return err;
}
This keeps the line count at minimum.
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
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_
>> + 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_
> 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/
>> @@ -616,7 +616,12 @@
>>
>> if (hip_select_
>> HIP_ERROR("Cannot find source address\n");
>> - return -1;
>> + if (hipl_is_
>> + memset(
> 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:/
"Branch merges" section of this page is up-to-date.
Xin
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
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://
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_
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/
>>> @@ -616,7 +616,12 @@
>>>
>>> if (hip_select_
>>> HIP_ERROR("Cannot find source address\n");
>>> - return -1;
>>> + if (hipl_is_
>>> + memset(
>> 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
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?
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_
const sockfd
> + is_ipv4 = (src_addr.sa_family == AF_INET);
> + if (is_ipv4) {
> + saddr4 = (struct sockaddr_in *) &src_addr;
> + IPV4_TO_
> + ctx->msg_
> + } else {
> + saddr6 = (struct sockaddr_in6 *) &src_addr;
> + memcpy(
a plain assignment instead of memcpy is easier to read in such cases, but that is a matter of taste.
> + ctx->msg_
> + }
Some of the socket_wrapper functions fit in very well here.
> + HIP_DEBUG_
> + HIP_DEBUG_
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/
> --- lib/hipdaemon/
> +++ lib/hipdaemon/
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_
> + const struct in6_addr *peer_addr)
> +{
> + return hip_hadb_
> +}
What's the point? Why not call hip_hadb_
More to come
Stefan
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
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_
>> + ctx->msg_
>> + } else {
>> + saddr6 = (struct sockaddr_in6 *) &src_addr;
>> + memcpy(
>
> 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(). :)
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_
> > + ctx->msg_
> > + } else {
> > + saddr6 = (struct sockaddr_in6 *) &src_addr;
> > + memcpy(
>
> 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
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://
>
> 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_
> 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
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.
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.
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
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_
In linkedlist.c
void hip_ll_
*const ptr,
... ....
}
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
Xin (eric-nevup) wrote : Posted in a previous version of this proposal | # |
On 27/02/12 10:04, Stefan Götz wrote:
>
>> + ctx->msg_
>> + }
> 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_
>> + const struct in6_addr *peer_addr)
>> +{
>> + return hip_hadb_
>> +}
> What's the point? Why not call hip_hadb_
>
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
Stefan Götz (stefan.goetz-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
>>
>>> + ctx->msg_
>>> + }
>> Some of the socket_wrapper functions fit in very well here.
>
> Didn't get your point, which function?
I meant get_port_
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_
>
>
This get_port_
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
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
Stefan Götz (stefan.goetz-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
Sorry, no time for more reviews :-(
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.
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
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
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
Christof Mroz (christof-mroz) wrote : | # |
> === 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>
> + <emphasis>
> + <emphasis>
> + </para>
A <code> tag looks more appropriate than <emphasis> (also in other places throught the file)
http://
> === added file 'lib/hipl/
> --- lib/hipl/
> +++ lib/hipl/
> @@ -0,0 +1,827 @@
> + do {
> + if (fd_info->proto == IPPROTO_TCP) {
> + if (!hip_read_
> + hip_receive_
> + }
> + } else if (fd_info->family == AF_INET) {
> + if (!hip_read_
> + hip_receive_
> + }
> + } else {
> + if (!hip_read_
> + hip_receive_
> + }
> + }
> + } while (fd_info->ha->state != HIP_STATE_
Looks like a lot of this dispatching throughout the patch could be avoided by introducing a generic hip_read_
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_
> + peer_addr6 = &peer_addr;
> + } else {
peer_addr is probably a useless indirection.
> === added file 'lib/hipl/
> --- lib/hipl/
> +++ lib/hipl/
> @@ -0,0 +1,52 @@
> +int hipl...
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-
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.
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.
Diego Biurrun (diego-biurrun) wrote : | # |
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)
> 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/performanc
I think tools/ would be a better place for this.
> @@ -59,15 +60,19 @@
>
> ### libraries ###
> lib_LTLIBRARIES = lib/core/
> +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_
> + lib/hipl/cert.c \
> + modules/
> + modules/
> + modules/
> + modules/
> + modules/
> + modules/
> +
> +lib_hipl_
> + modules/
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_
Place this together with the other lib dependencies.
> @@ -216,10 +225,13 @@
> test_check_
> test/lib/
> test/lib/core/hit.c \
> test/lib/
> + test/lib/
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>
> +...
- 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.
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://
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
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://
>
> 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
- 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
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[
>> @@ -743,11 +745,16 @@
>> goto out_err;
>> }
>> } else if (!use_default) {
>> + hi_file_dup = strdup(hi_file);
>> + if ((err = check_and_
>> + 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_
>> +{
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
>> + //hip_register_
> 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
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[
>>> >> @@ -743,11 +745,16 @@
>>> >> goto out_err;
>>> >> }
>>> >> } else if (!use_default) {
>>> >> + hi_file_dup = strdup(hi_file);
>>> >> + if ((err = check_and_
>>> >> + 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_
Unmerged revisions
Preview Diff
1 | === modified file 'Makefile.am' |
2 | --- Makefile.am 2012-03-13 15:27:06 +0000 |
3 | +++ Makefile.am 2012-04-17 15:16:21 +0000 |
4 | @@ -58,17 +58,21 @@ |
5 | |
6 | |
7 | ### libraries ### |
8 | -lib_LTLIBRARIES = lib/core/libhipcore.la |
9 | +lib_LTLIBRARIES = lib/core/libhipcore.la \ |
10 | + lib/hipl/libhipl.la |
11 | |
12 | |
13 | ### tests ### |
14 | if HIP_UNITTESTS |
15 | TESTS = test/check_hipd \ |
16 | test/check_hipfw \ |
17 | - test/check_lib_core |
18 | + test/check_lib_core \ |
19 | + test/check_libhipl |
20 | + |
21 | check_PROGRAMS = test/check_hipd \ |
22 | test/check_hipfw \ |
23 | - test/check_lib_core |
24 | + test/check_lib_core \ |
25 | + test/check_libhipl |
26 | endif |
27 | |
28 | |
29 | @@ -85,47 +89,7 @@ |
30 | |
31 | tools_hipconf_SOURCES = tools/hipconf.c |
32 | |
33 | -hipd_hipd_sources = hipd/accessor.c \ |
34 | - hipd/cert.c \ |
35 | - hipd/close.c \ |
36 | - hipd/configfilereader.c \ |
37 | - hipd/cookie.c \ |
38 | - hipd/dh.c \ |
39 | - hipd/esp_prot_anchordb.c \ |
40 | - hipd/esp_prot_hipd_msg.c \ |
41 | - hipd/esp_prot_light_update.c \ |
42 | - hipd/hadb.c \ |
43 | - hipd/hidb.c \ |
44 | - hipd/hip_socket.c \ |
45 | - hipd/hipd.c \ |
46 | - hipd/hiprelay.c \ |
47 | - hipd/hit_to_ip.c \ |
48 | - hipd/init.c \ |
49 | - hipd/input.c \ |
50 | - hipd/keymat.c \ |
51 | - hipd/lsidb.c \ |
52 | - hipd/maintenance.c \ |
53 | - hipd/nat.c \ |
54 | - hipd/netdev.c \ |
55 | - hipd/nsupdate.c \ |
56 | - hipd/opp_mode.c \ |
57 | - hipd/output.c \ |
58 | - hipd/pkt_handling.c \ |
59 | - hipd/registration.c \ |
60 | - hipd/user.c \ |
61 | - hipd/user_ipsec_hipd_msg.c \ |
62 | - hipd/user_ipsec_sadb_api.c \ |
63 | - modules/heartbeat/hipd/heartbeat.c \ |
64 | - modules/heartbeat_update/hipd/hb_update.c \ |
65 | - modules/cert/hipd/cert.c \ |
66 | - modules/update/hipd/update.c \ |
67 | - modules/update/hipd/update_builder.c \ |
68 | - modules/update/hipd/update_locator.c \ |
69 | - modules/update/hipd/update_param_handling.c |
70 | - |
71 | -hipd_hipd_SOURCES = $(hipd_hipd_sources) \ |
72 | - modules/midauth/hipd/midauth.c \ |
73 | - hipd/main.c |
74 | +hipd_hipd_SOURCES = hipd/main.c |
75 | |
76 | dist_sysconf_DATA = hipd/hipd.conf \ |
77 | hipd/hosts \ |
78 | @@ -202,6 +166,47 @@ |
79 | lib_core_libhipcore_la_SOURCES += lib/core/performance.c |
80 | endif |
81 | |
82 | +lib_hipl_libhipl_la_SOURCES = lib/hipl/accessor.c \ |
83 | + lib/hipl/cert.c \ |
84 | + lib/hipl/close.c \ |
85 | + lib/hipl/configfilereader.c \ |
86 | + lib/hipl/cookie.c \ |
87 | + lib/hipl/dh.c \ |
88 | + lib/hipl/esp_prot_anchordb.c \ |
89 | + lib/hipl/esp_prot_hipd_msg.c \ |
90 | + lib/hipl/esp_prot_light_update.c \ |
91 | + lib/hipl/hadb.c \ |
92 | + lib/hipl/hidb.c \ |
93 | + lib/hipl/hip_socket.c \ |
94 | + lib/hipl/hipd.c \ |
95 | + lib/hipl/hiprelay.c \ |
96 | + lib/hipl/hit_to_ip.c \ |
97 | + lib/hipl/init.c \ |
98 | + lib/hipl/input.c \ |
99 | + lib/hipl/keymat.c \ |
100 | + lib/hipl/lhipl.c \ |
101 | + lib/hipl/lhipl_sock.c \ |
102 | + lib/hipl/lhipl_operations.c \ |
103 | + lib/hipl/lsidb.c \ |
104 | + lib/hipl/maintenance.c \ |
105 | + lib/hipl/nat.c \ |
106 | + lib/hipl/netdev.c \ |
107 | + lib/hipl/nsupdate.c \ |
108 | + lib/hipl/opp_mode.c \ |
109 | + lib/hipl/output.c \ |
110 | + lib/hipl/pkt_handling.c \ |
111 | + lib/hipl/registration.c \ |
112 | + lib/hipl/user.c \ |
113 | + lib/hipl/user_ipsec_hipd_msg.c \ |
114 | + lib/hipl/user_ipsec_sadb_api.c \ |
115 | + modules/cert/hipd/cert.c \ |
116 | + modules/heartbeat/hipd/heartbeat.c \ |
117 | + modules/heartbeat_update/hipd/hb_update.c \ |
118 | + modules/midauth/hipd/midauth.c \ |
119 | + modules/update/hipd/update.c \ |
120 | + modules/update/hipd/update_builder.c \ |
121 | + modules/update/hipd/update_locator.c \ |
122 | + modules/update/hipd/update_param_handling.c |
123 | |
124 | test_check_hipd_SOURCES = test/check_hipd.c \ |
125 | test/hipd/lsidb.c \ |
126 | @@ -230,14 +235,18 @@ |
127 | test/lib/core/gpl/pk.c \ |
128 | test/lib/core/modules/midauth_builder.c |
129 | |
130 | +test_check_libhipl_SOURCES = test/check_libhipl.c |
131 | + |
132 | |
133 | ### static library dependencies ### |
134 | |
135 | -hipd_hipd_LDADD = lib/core/libhipcore.la |
136 | +hipd_hipd_LDADD = lib/hipl/libhipl.la |
137 | hipfw_hipfw_LDADD = lib/core/libhipcore.la |
138 | -test_check_hipd_LDADD = lib/core/libhipcore.la |
139 | +lib_hipl_libhipl_la_LIBADD = lib/core/libhipcore.la |
140 | +test_check_hipd_LDADD = lib/hipl/libhipl.la |
141 | test_check_hipfw_LDADD = lib/core/libhipcore.la |
142 | test_check_lib_core_LDADD = lib/core/libhipcore.la |
143 | +test_check_libhipl_LDADD = lib/hipl/libhipl.la |
144 | test_certteststub_LDADD = lib/core/libhipcore.la |
145 | test_performance_auth_performance_LDADD = lib/core/libhipcore.la |
146 | test_performance_dh_performance_LDADD = lib/core/libhipcore.la |
147 | |
148 | === modified file 'doc/HOWTO.xml.in' |
149 | --- doc/HOWTO.xml.in 2012-02-28 18:38:18 +0000 |
150 | +++ doc/HOWTO.xml.in 2012-04-17 15:16:21 +0000 |
151 | @@ -2659,6 +2659,112 @@ |
152 | |
153 | </section> |
154 | |
155 | + <section id="ch_libhipl_usage"> |
156 | + <title>The Libhipl Extension</title> |
157 | + |
158 | + <para> |
159 | + Libhipl provides HIP functionality as a library for upper layer |
160 | + applications and it does not require the presence of the HIPL daemon. |
161 | + Instead, the HIP control messages are transmitted on top of TCP/UDP. |
162 | + From the applications' point of view, there is an API similar to the |
163 | + normal socket API. This section describes the libhipl API. |
164 | + </para> |
165 | + |
166 | + <para> |
167 | + Libhipl API set is located in <emphasis>"lhipl.h"</emphasis>. Refer to |
168 | + its API documentation for detail information of each function. |
169 | + </para> |
170 | + |
171 | + <formalpara> |
172 | + <title>Libhipl initialization</title> |
173 | + <para> |
174 | + Libhipl requires initialization before calling any other related |
175 | + functions. The function: <emphasis>hipl_lib_init_all()</emphasis> |
176 | + serves this purpose and different debug levels can be set as its |
177 | + parameters to track problems inside the library. |
178 | + </para> |
179 | + </formalpara> |
180 | + |
181 | + <formalpara> |
182 | + <title>Name-based API</title> |
183 | + <para> |
184 | + Compared to standard socket API, one apparent difference in Libhipl is |
185 | + that a peer is specified by given a peer name and a port number instead |
186 | + of a sockaddr data structure. The peer name is a string representation of |
187 | + the peer. Currently, Libhipl only support HIT string as peer name. |
188 | + </para> |
189 | + </formalpara> |
190 | + |
191 | + <formalpara> |
192 | + <title>Libhipl socket creation</title> |
193 | + <para> |
194 | + The function hipl_socket() creates a new libhipl socket. An ID is |
195 | + assigned to each created libhipl socket and returned by this function, |
196 | + then caller can pass this ID to other libhipl functions to operates on |
197 | + this libhipl socket. NOTE: there is NO relation between libhipl socket |
198 | + ID and normal socket file descriptor, and the result of using |
199 | + this ID as file descriptor is undefined. |
200 | + </para> |
201 | + </formalpara> |
202 | + |
203 | + <formalpara><title>Setup TCP connection</title><para> |
204 | + When using libhipl in TCP mode, TCP connection setup is the first task. |
205 | + similar to the normal socket syntax, libhipl provides: |
206 | + <emphasis>hipl_connect()</emphasis>, <emphasis>hipl_listen()</emphasis> |
207 | + and <emphasis>hipl_accept()</emphasis> for this goal. Those functions |
208 | + process the 3-way handshake and establish a TCP connection. |
209 | + </para></formalpara> |
210 | + |
211 | + <formalpara> |
212 | + <title>libhipl Base Exchange (BEX) and user data transmission</title> |
213 | + <para> |
214 | + Data transmission is handled by <emphasis>hipl_sendto()</emphasis> and |
215 | + <emphasis>hipl_recvfrom()</emphasis>. |
216 | + In libhipl, The first sending data call triggers BEX and the first |
217 | + receiving call waits for incoming BEX message. Once BEX succeeds, |
218 | + the pending user data is transmitted to the peer side. This BEX process |
219 | + is handled by libhipl automatically by default. Meanwhile, we also |
220 | + provide an advanced way to handle BEX step by step, which we will |
221 | + explain bellow. |
222 | + </para> |
223 | + </formalpara> |
224 | + |
225 | + <formalpara> |
226 | + <title>libhipl assistant API</title> |
227 | + <para> |
228 | + <itemizedlist> |
229 | + <listitem> |
230 | + <para> |
231 | + <emphasis>hipl_add_peer_info()</emphasis> adds peer's HIT and IP |
232 | + address mappings to the database of libhipl. The library can use |
233 | + this information to look up peer's locator when a peer name is |
234 | + given. |
235 | + </para> |
236 | + </listitem> |
237 | + |
238 | + <listitem> |
239 | + <para> |
240 | + <emphasis>hipl_lib_set_bex_feedback()</emphasis>: This function |
241 | + turns on/off the step-by-step process of BEX. By default, BEX |
242 | + feedback is off. When it is on, sending/receiving functions only |
243 | + process one BEX messages at a time, and give different return |
244 | + values to notify the progress of BEX. |
245 | + </para> |
246 | + </listitem> |
247 | + </itemizedlist> |
248 | + </para> |
249 | + </formalpara> |
250 | + |
251 | + <formalpara> |
252 | + <title>Libhipl sample program</title> |
253 | + <para> |
254 | + For a libhipl usage example, refer to the |
255 | + <emphasis>check_libhipl</emphasis> program in the |
256 | + <emphasis>test</emphasis> directory. |
257 | + </para> |
258 | + </formalpara> |
259 | + |
260 | + </section> <!-- ch_libhipl_usage --> |
261 | </chapter> <!-- ch_exp_extensions --> |
262 | |
263 | </book> |
264 | |
265 | === modified file 'hipd/main.c' |
266 | --- hipd/main.c 2011-11-03 09:21:12 +0000 |
267 | +++ hipd/main.c 2012-04-17 15:16:21 +0000 |
268 | @@ -1,5 +1,5 @@ |
269 | /* |
270 | - * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
271 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
272 | * |
273 | * Permission is hereby granted, free of charge, to any person |
274 | * obtaining a copy of this software and associated documentation |
275 | @@ -32,10 +32,9 @@ |
276 | #include <unistd.h> |
277 | #include <sys/types.h> |
278 | |
279 | - |
280 | -#include "hipd/hipd.h" |
281 | -#include "init.h" |
282 | #include "lib/core/debug.h" |
283 | +#include "lib/hipl/hipd.h" |
284 | +#include "lib/hipl/init.h" |
285 | |
286 | |
287 | /** |
288 | |
289 | === modified file 'hipfw/hipfw.c' |
290 | --- hipfw/hipfw.c 2012-04-16 14:55:53 +0000 |
291 | +++ hipfw/hipfw.c 2012-04-17 15:16:21 +0000 |
292 | @@ -75,7 +75,7 @@ |
293 | #include "lib/core/performance.h" |
294 | #include "lib/core/prefix.h" |
295 | #include "lib/core/util.h" |
296 | -#include "hipd/hipd.h" |
297 | +#include "lib/hipl/hipd.h" |
298 | #include "config.h" |
299 | #include "cache.h" |
300 | #include "cert.h" |
301 | |
302 | === modified file 'lib/core/hostid.c' |
303 | --- lib/core/hostid.c 2012-03-01 14:26:43 +0000 |
304 | +++ lib/core/hostid.c 2012-04-17 15:16:21 +0000 |
305 | @@ -1,5 +1,5 @@ |
306 | /* |
307 | - * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
308 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
309 | * |
310 | * Permission is hereby granted, free of charge, to any person |
311 | * obtaining a copy of this software and associated documentation |
312 | @@ -29,6 +29,7 @@ |
313 | */ |
314 | |
315 | #include <errno.h> |
316 | +#include <libgen.h> |
317 | #include <stdint.h> |
318 | #include <stdlib.h> |
319 | #include <string.h> |
320 | @@ -678,6 +679,7 @@ |
321 | int err = 0, dsa_key_rr_len = 0, rsa_key_rr_len = 0; |
322 | int dsa_pub_key_rr_len = 0, rsa_pub_key_rr_len = 0; |
323 | hip_hdr numeric_action = 0; |
324 | + char *hi_file_dup = NULL; |
325 | char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX]; |
326 | const char *rsa_filenamebase = DEFAULT_HOST_RSA_KEY_FILE_BASE DEFAULT_ANON_HI_FILE_NAME_SUFFIX; |
327 | const char *dsa_filenamebase = DEFAULT_HOST_DSA_KEY_FILE_BASE DEFAULT_ANON_HI_FILE_NAME_SUFFIX; |
328 | @@ -743,11 +745,16 @@ |
329 | goto out_err; |
330 | } |
331 | } else if (!use_default) { |
332 | + hi_file_dup = strdup(hi_file); |
333 | + if ((err = check_and_create_dir(dirname(hi_file_dup), HIP_DIR_MODE))) { |
334 | + HIP_ERROR("Could not create directory for path: %s\n", hi_file); |
335 | + goto out_err; |
336 | + } |
337 | if (!strcmp(hi_fmt, "dsa")) { |
338 | dsa_key = create_dsa_key(dsa_key_bits); |
339 | HIP_IFEL(!dsa_key, -EINVAL, |
340 | "Creation of DSA key failed.\n"); |
341 | - if ((err = save_dsa_private_key(dsa_filenamebase, dsa_key))) { |
342 | + if ((err = save_dsa_private_key(hi_file, dsa_key))) { |
343 | HIP_ERROR("Saving of DSA key failed.\n"); |
344 | goto out_err; |
345 | } |
346 | @@ -756,7 +763,7 @@ |
347 | ecdsa_key = create_ecdsa_key(ecdsa_nid); |
348 | HIP_IFEL(!ecdsa_key, -EINVAL, |
349 | "Creation of ECDSA key failed.\n"); |
350 | - if ((err = save_ecdsa_private_key(ecdsa_filenamebase, ecdsa_key))) { |
351 | + if ((err = save_ecdsa_private_key(hi_file, ecdsa_key))) { |
352 | HIP_ERROR("Saving of ECDSA key failed.\n"); |
353 | goto out_err; |
354 | } |
355 | @@ -765,7 +772,7 @@ |
356 | rsa_key = create_rsa_key(rsa_key_bits); |
357 | HIP_IFEL(!rsa_key, -EINVAL, |
358 | "Creation of RSA key failed.\n"); |
359 | - if ((err = save_rsa_private_key(rsa_filenamebase, rsa_key))) { |
360 | + if ((err = save_rsa_private_key(hi_file, rsa_key))) { |
361 | HIP_ERROR("Saving of RSA key failed.\n"); |
362 | goto out_err; |
363 | } |
364 | @@ -1093,6 +1100,7 @@ |
365 | change_key_file_perms(rsa_filenamebase_pub); |
366 | } |
367 | |
368 | + free(hi_file_dup); |
369 | free(dsa_host_id); |
370 | free(dsa_pub_host_id); |
371 | free(rsa_host_id); |
372 | |
373 | === added directory 'lib/hipl' |
374 | === renamed file 'hipd/accessor.c' => 'lib/hipl/accessor.c' |
375 | === renamed file 'hipd/accessor.h' => 'lib/hipl/accessor.h' |
376 | === renamed file 'hipd/cert.c' => 'lib/hipl/cert.c' |
377 | === renamed file 'hipd/cert.h' => 'lib/hipl/cert.h' |
378 | === renamed file 'hipd/close.c' => 'lib/hipl/close.c' |
379 | === renamed file 'hipd/close.h' => 'lib/hipl/close.h' |
380 | === renamed file 'hipd/configfilereader.c' => 'lib/hipl/configfilereader.c' |
381 | === renamed file 'hipd/configfilereader.h' => 'lib/hipl/configfilereader.h' |
382 | === renamed file 'hipd/cookie.c' => 'lib/hipl/cookie.c' |
383 | === renamed file 'hipd/cookie.h' => 'lib/hipl/cookie.h' |
384 | === renamed file 'hipd/dh.c' => 'lib/hipl/dh.c' |
385 | === renamed file 'hipd/dh.h' => 'lib/hipl/dh.h' |
386 | === renamed file 'hipd/esp_prot_anchordb.c' => 'lib/hipl/esp_prot_anchordb.c' |
387 | === renamed file 'hipd/esp_prot_anchordb.h' => 'lib/hipl/esp_prot_anchordb.h' |
388 | === renamed file 'hipd/esp_prot_hipd_msg.c' => 'lib/hipl/esp_prot_hipd_msg.c' |
389 | === renamed file 'hipd/esp_prot_hipd_msg.h' => 'lib/hipl/esp_prot_hipd_msg.h' |
390 | === renamed file 'hipd/esp_prot_light_update.c' => 'lib/hipl/esp_prot_light_update.c' |
391 | === renamed file 'hipd/esp_prot_light_update.h' => 'lib/hipl/esp_prot_light_update.h' |
392 | === renamed file 'hipd/hadb.c' => 'lib/hipl/hadb.c' |
393 | --- hipd/hadb.c 2012-03-20 13:08:56 +0000 |
394 | +++ lib/hipl/hadb.c 2012-04-17 15:16:21 +0000 |
395 | @@ -608,9 +608,15 @@ |
396 | HIP_HOST_ID_HOSTNAME_LEN_MAX - 1); |
397 | } |
398 | |
399 | - if (hip_select_source_address(&peer_map.our_addr, &peer_map.peer_addr)) { |
400 | + /* hip_select_source_address() is incompatible with libhipl, therefore we skip |
401 | + * this function and set the source address in peer_map to the ANY source |
402 | + * address.*/ |
403 | + if (!hipl_is_libhip_mode() |
404 | + && hip_select_source_address(&peer_map.our_addr, &peer_map.peer_addr)) { |
405 | HIP_ERROR("Cannot find source address\n"); |
406 | return -1; |
407 | + } else if (hipl_is_libhip_mode()) { |
408 | + memset(&peer_map.our_addr, 0, sizeof(peer_map.our_addr)); |
409 | } |
410 | |
411 | if (hip_for_each_hi(hadb_add_peer_info_wrapper, &peer_map)) { |
412 | @@ -1451,6 +1457,10 @@ |
413 | */ |
414 | void hip_delete_security_associations_and_sp(struct hip_hadb_state *const ha) |
415 | { |
416 | + if (hipl_is_libhip_mode()) { |
417 | + return; |
418 | + } |
419 | + |
420 | // Delete previous security policies |
421 | hip_delete_hit_sp_pair(&ha->hit_our, &ha->hit_peer, 1); |
422 | hip_delete_hit_sp_pair(&ha->hit_peer, &ha->hit_our, 1); |
423 | @@ -1520,6 +1530,11 @@ |
424 | ha), |
425 | -1, "Error while changing outbound security association\n"); |
426 | |
427 | + if (hipl_is_libhip_mode()) { |
428 | + HIP_DEBUG("No SP set up in library mode\n"); |
429 | + goto out_err; |
430 | + } |
431 | + |
432 | // Create a new security policy pointing to SAs after SA setup |
433 | HIP_IFEL(hip_setup_hit_sp_pair(&ha->hit_peer, |
434 | &ha->hit_our, |
435 | |
436 | === renamed file 'hipd/hadb.h' => 'lib/hipl/hadb.h' |
437 | === renamed file 'hipd/hidb.c' => 'lib/hipl/hidb.c' |
438 | --- hipd/hidb.c 2012-04-17 11:20:20 +0000 |
439 | +++ lib/hipl/hidb.c 2012-04-17 15:16:21 +0000 |
440 | @@ -596,13 +596,15 @@ |
441 | hip_add_iface_local_route(&in6_lsi); |
442 | |
443 | /* Adding HITs and LSIs to the interface */ |
444 | - if (hip_add_iface_local_hit(&hit)) { |
445 | - HIP_ERROR("Failed to add HIT to the device\n"); |
446 | - return -1; |
447 | - } |
448 | - if (hip_add_iface_local_hit(&in6_lsi)) { |
449 | - HIP_ERROR("Failed to add LSI to the device\n"); |
450 | - return -1; |
451 | + if (!hipl_is_libhip_mode()) { |
452 | + if (hip_add_iface_local_hit(&hit)) { |
453 | + HIP_ERROR("Failed to add HIT to the device\n"); |
454 | + return -1; |
455 | + } |
456 | + if (hip_add_iface_local_hit(&in6_lsi)) { |
457 | + HIP_ERROR("Failed to add LSI to the device\n"); |
458 | + return -1; |
459 | + } |
460 | } |
461 | } |
462 | |
463 | |
464 | === renamed file 'hipd/hidb.h' => 'lib/hipl/hidb.h' |
465 | === renamed file 'hipd/hip_socket.c' => 'lib/hipl/hip_socket.c' |
466 | === renamed file 'hipd/hip_socket.h' => 'lib/hipl/hip_socket.h' |
467 | === renamed file 'hipd/hipd.c' => 'lib/hipl/hipd.c' |
468 | === renamed file 'hipd/hipd.h' => 'lib/hipl/hipd.h' |
469 | --- hipd/hipd.h 2012-03-20 21:45:03 +0000 |
470 | +++ lib/hipl/hipd.h 2012-04-17 15:16:21 +0000 |
471 | @@ -27,6 +27,7 @@ |
472 | #define HIPL_HIPD_HIPD_H |
473 | |
474 | #include <netdb.h> |
475 | +#include <stdbool.h> |
476 | #include <stdint.h> |
477 | #include <netinet/in.h> |
478 | #include <sys/types.h> |
479 | @@ -80,4 +81,8 @@ |
480 | int hipd_parse_cmdline_opts(int argc, char *argv[], uint64_t * flags); |
481 | int hipd_main(uint64_t flags); |
482 | |
483 | +/* libhip_mode accessor */ |
484 | +bool hipl_is_libhip_mode(void); |
485 | +void hipl_set_libhip_mode(void); |
486 | + |
487 | #endif /* HIPL_HIPD_HIPD_H */ |
488 | |
489 | === renamed file 'hipd/hiprelay.c' => 'lib/hipl/hiprelay.c' |
490 | === renamed file 'hipd/hiprelay.h' => 'lib/hipl/hiprelay.h' |
491 | === renamed file 'hipd/hit_to_ip.c' => 'lib/hipl/hit_to_ip.c' |
492 | === renamed file 'hipd/hit_to_ip.h' => 'lib/hipl/hit_to_ip.h' |
493 | === renamed file 'hipd/init.c' => 'lib/hipl/init.c' |
494 | --- hipd/init.c 2012-04-16 14:47:42 +0000 |
495 | +++ lib/hipl/init.c 2012-04-17 15:16:21 +0000 |
496 | @@ -34,7 +34,9 @@ |
497 | |
498 | #include <errno.h> |
499 | #include <limits.h> |
500 | +#include <pwd.h> |
501 | #include <signal.h> |
502 | +#include <stdbool.h> |
503 | #include <stdint.h> |
504 | #include <stdlib.h> |
505 | #include <string.h> |
506 | @@ -118,6 +120,34 @@ |
507 | #endif |
508 | /** end ICMPV6_FILTER related stuff */ |
509 | |
510 | +#define HIPL_USER_DIR ".hipl" |
511 | +#define HIPL_USER_RSA_KEY_NAME "hipl_lib_rsa_key" |
512 | + |
513 | +/* Flag to show if hipl is running in libhip mode (=1) or normal mode (=0). |
514 | + * |
515 | + * This variable should NOT be accessed directly. Always use the accessor |
516 | + * functions instead. |
517 | + */ |
518 | +static bool hipd_library_mode = false; |
519 | + |
520 | +/** |
521 | + * Test if the library mode is on. |
522 | + * |
523 | + * @return true if the library mode is on, false otherwise. |
524 | + */ |
525 | +bool hipl_is_libhip_mode(void) |
526 | +{ |
527 | + return hipd_library_mode; |
528 | +} |
529 | + |
530 | +/** |
531 | + * Turn on library mode. |
532 | + */ |
533 | +void hipl_set_libhip_mode(void) |
534 | +{ |
535 | + hipd_library_mode = true; |
536 | +} |
537 | + |
538 | /* Startup flags of the HIPD. Keep the around, for they will be used at exit */ |
539 | static uint64_t sflags; |
540 | |
541 | @@ -523,6 +553,199 @@ |
542 | lmod_register_packet_type(HIP_LUPDATE, "HIP_LUPDATE"); |
543 | } |
544 | |
545 | +static int libhip_init_handle_functions(void) |
546 | +{ |
547 | + HIP_DEBUG("Initialize handle functions for libhip.\n"); |
548 | + |
549 | + hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_check_i1, 20000); |
550 | + hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_handle_i1, 30000); |
551 | + hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_update_retransmissions, 35000); |
552 | + hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_send_r1, 40000); |
553 | + hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_check_i1, 20000); |
554 | + hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_handle_i1, 30000); |
555 | + hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_update_retransmissions, 35000); |
556 | + hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_send_r1, 40000); |
557 | + hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_check_i1, 20000); |
558 | + hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_handle_i1, 30000); |
559 | + hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_update_retransmissions, 35000); |
560 | + hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_send_r1, 40000); |
561 | + hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_check_i1, 20000); |
562 | + hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_handle_i1, 30000); |
563 | + hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_update_retransmissions, 35000); |
564 | + hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_send_r1, 40000); |
565 | + hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_check_i1, 20000); |
566 | + hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_handle_i1, 30000); |
567 | + hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 35000); |
568 | + hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_send_r1, 40000); |
569 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_check_i1, 20000); |
570 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_handle_i1, 30000); |
571 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_update_retransmissions, 35000); |
572 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_send_r1, 40000); |
573 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_check_i1, 20000); |
574 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_handle_i1, 30000); |
575 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_update_retransmissions, 35000); |
576 | + hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_send_r1, 40000); |
577 | + hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_check_i1, 20000); |
578 | + hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_handle_i1, 30000); |
579 | + hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_update_retransmissions, 35000); |
580 | + hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_send_r1, 40000); |
581 | + |
582 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_check_i2, 20000); |
583 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_handle_i2, 30000); |
584 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_update_retransmissions, 30250); |
585 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_create_r2, 40000); |
586 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_add_rvs_reg_from, 41000); |
587 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_hmac2_and_sign, 42000); |
588 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_add_rvs_relay_to, 43000); |
589 | + hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_send_r2, 50000); |
590 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_check_i2, 20000); |
591 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_handle_i2, 30000); |
592 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_update_retransmissions, 30250); |
593 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_create_r2, 40000); |
594 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_add_rvs_reg_from, 41000); |
595 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_hmac2_and_sign, 42000); |
596 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_add_rvs_relay_to, 43000); |
597 | + hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_send_r2, 50000); |
598 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_check_i2, 20000); |
599 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2_in_i2_sent, 21000); |
600 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2, 30000); |
601 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30250); |
602 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_create_r2, 40000); |
603 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_add_rvs_reg_from, 41000); |
604 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_hmac2_and_sign, 42000); |
605 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_add_rvs_relay_to, 43000); |
606 | + hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_send_r2, 50000); |
607 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_check_i2, 20000); |
608 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_handle_i2, 30000); |
609 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_update_retransmissions, 30250); |
610 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_create_r2, 40000); |
611 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_add_rvs_reg_from, 41000); |
612 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_hmac2_and_sign, 42000); |
613 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_add_rvs_relay_to, 43000); |
614 | + hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_send_r2, 50000); |
615 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_check_i2, 20000); |
616 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_handle_i2, 30000); |
617 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 30250); |
618 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_create_r2, 40000); |
619 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_add_rvs_reg_from, 41000); |
620 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_hmac2_and_sign, 42000); |
621 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_add_rvs_relay_to, 43000); |
622 | + hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_send_r2, 50000); |
623 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_check_i2, 20000); |
624 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_handle_i2, 30000); |
625 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_update_retransmissions, 30250); |
626 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_create_r2, 40000); |
627 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_add_rvs_reg_from, 41000); |
628 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_hmac2_and_sign, 42000); |
629 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_add_rvs_relay_to, 43000); |
630 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_send_r2, 50000); |
631 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_check_i2, 20000); |
632 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_handle_i2, 30000); |
633 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_update_retransmissions, 30250); |
634 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_create_r2, 40000); |
635 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_add_rvs_reg_from, 41000); |
636 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_hmac2_and_sign, 42000); |
637 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_add_rvs_relay_to, 43000); |
638 | + hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_send_r2, 50000); |
639 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_check_i2, 20000); |
640 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_handle_i2, 30000); |
641 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_update_retransmissions, 30250); |
642 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_create_r2, 40000); |
643 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_add_rvs_reg_from, 41000); |
644 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_hmac2_and_sign, 42000); |
645 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_add_rvs_relay_to, 43000); |
646 | + hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_send_r2, 50000); |
647 | + |
648 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_check_r1, 20000); |
649 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_r1, 30000); |
650 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_update_retransmissions, 30500); |
651 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_esp_info, 31000); |
652 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_solution, 32000); |
653 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_diffie_hellman, 33000); |
654 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &esp_prot_r1_handle_transforms, 34000); |
655 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_create_i2, 40000); |
656 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_add_signed_echo_response, 41000); |
657 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_mac_and_sign_handler, 42000); |
658 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_add_unsigned_echo_response, 43000); |
659 | + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_send_i2, 50000); |
660 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_check_r1, 20000); |
661 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_r1, 30000); |
662 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30500); |
663 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_esp_info, 31000); |
664 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_solution, 32000); |
665 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_diffie_hellman, 33000); |
666 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &esp_prot_r1_handle_transforms, 34000); |
667 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_create_i2, 40000); |
668 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_add_signed_echo_response, 41000); |
669 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_mac_and_sign_handler, 42000); |
670 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_add_unsigned_echo_response, 43000); |
671 | + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_send_i2, 50000); |
672 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_check_r1, 20000); |
673 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_r1, 30000); |
674 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_update_retransmissions, 30500); |
675 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_esp_info, 31000); |
676 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_solution, 32000); |
677 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_diffie_hellman, 33000); |
678 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &esp_prot_r1_handle_transforms, 34000); |
679 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_create_i2, 40000); |
680 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_add_signed_echo_response, 41000); |
681 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_mac_and_sign_handler, 42000); |
682 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_add_unsigned_echo_response, 43000); |
683 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_send_i2, 50000); |
684 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_check_r1, 20000); |
685 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_r1, 30000); |
686 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_update_retransmissions, 30500); |
687 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_esp_info, 31000); |
688 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_solution, 32000); |
689 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_diffie_hellman, 33000); |
690 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &esp_prot_r1_handle_transforms, 34000); |
691 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_create_i2, 40000); |
692 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_add_signed_echo_response, 41000); |
693 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_mac_and_sign_handler, 42000); |
694 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_add_unsigned_echo_response, 43000); |
695 | + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_send_i2, 50000); |
696 | + |
697 | + hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_check_r2, 20000); |
698 | + hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_handle_r2, 30000); |
699 | + hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30250); |
700 | + |
701 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_check_notify, 20000); |
702 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_handle_notify, 30000); |
703 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I2_SENT, &hip_check_notify, 20000); |
704 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I2_SENT, &hip_handle_notify, 30000); |
705 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_R2_SENT, &hip_check_notify, 20000); |
706 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_R2_SENT, &hip_handle_notify, 30000); |
707 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_ESTABLISHED, &hip_check_notify, 20000); |
708 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_ESTABLISHED, &hip_handle_notify, 30000); |
709 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSING, &hip_check_notify, 20000); |
710 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSING, &hip_handle_notify, 30000); |
711 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_check_notify, 20000); |
712 | + hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_handle_notify, 30000); |
713 | + |
714 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_check_packet, 20000); |
715 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 25000); |
716 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_create_response, 30000); |
717 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_send_response, 40000); |
718 | + |
719 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_check_packet, 20000); |
720 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_update_retransmissions, 25000); |
721 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_create_response, 30000); |
722 | + hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_send_response, 40000); |
723 | + |
724 | + hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_check_packet, 20000); |
725 | + hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_update_retransmissions, 25000); |
726 | + hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_handle_packet, 30000); |
727 | + |
728 | + hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_check_packet, 20000); |
729 | + hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_update_retransmissions, 25000); |
730 | + hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_handle_packet, 30000); |
731 | + |
732 | + hip_register_handle_function(HIP_LUPDATE, HIP_STATE_ESTABLISHED, &esp_prot_handle_light_update, 20000); |
733 | + hip_register_handle_function(HIP_LUPDATE, HIP_STATE_R2_SENT, &esp_prot_handle_light_update, 20000); |
734 | + |
735 | + return 0; |
736 | +} |
737 | + |
738 | static int init_handle_functions(void) |
739 | { |
740 | int err = 0; |
741 | @@ -1090,6 +1313,80 @@ |
742 | } |
743 | |
744 | /** |
745 | + * Initialization function for libhipl. |
746 | + * |
747 | + * @param debug_level debug level for log output. |
748 | + * @return 0 on success, negative number on errors. |
749 | + */ |
750 | +int hipl_lib_init(enum logdebug debug_level) |
751 | +{ |
752 | + int err = 0; |
753 | + int keypath_len = 0; |
754 | + char *key_path = NULL; |
755 | + struct hip_common *msg = NULL; |
756 | + struct passwd *pwd; |
757 | + |
758 | + hipl_set_libhip_mode(); |
759 | + hip_nat_status = 1; |
760 | + |
761 | + /* disable hip_firewall */ |
762 | + lsi_status = HIP_MSG_LSI_OFF; |
763 | + |
764 | + /* set the initial verbosity level */ |
765 | + hip_set_logdebug(debug_level); |
766 | + |
767 | + hip_init_hadb(); |
768 | + hip_init_hostid_db(); |
769 | + hip_netdev_init_addresses(); |
770 | + libhip_init_handle_functions(); |
771 | + |
772 | + /* Load default key from ~/.hipl/ */ |
773 | + if ((pwd = getpwuid(getuid())) == NULL) { |
774 | + return -1; |
775 | + } |
776 | + |
777 | + /* +3 because we need 2 slashes and a NULL for termination */ |
778 | + keypath_len = strlen(pwd->pw_dir) + |
779 | + strlen(HIPL_USER_DIR) + |
780 | + strlen(HIPL_USER_RSA_KEY_NAME) + |
781 | + strlen(DEFAULT_PUB_HI_FILE_NAME_SUFFIX) + 3; |
782 | + if ((key_path = malloc(keypath_len)) == NULL) { |
783 | + HIP_ERROR("malloc() failed\n"); |
784 | + return -ENOMEM; |
785 | + } |
786 | + |
787 | + HIP_IFEL(snprintf(key_path, keypath_len, "%s/%s/%s%s", pwd->pw_dir, |
788 | + HIPL_USER_DIR, |
789 | + HIPL_USER_RSA_KEY_NAME, |
790 | + DEFAULT_PUB_HI_FILE_NAME_SUFFIX) < 0, |
791 | + -1, "snprintf() failed"); |
792 | + |
793 | + HIP_DEBUG("Using key: %s\n", key_path); |
794 | + HIP_IFEL(!(msg = hip_msg_alloc()), -ENOMEM, "hip_msg_alloc()"); |
795 | + if (hip_serialize_host_id_action(msg, ACTION_ADD, 0, 0, "rsa", |
796 | + key_path, 0, 0, 0)) { |
797 | + free(msg); |
798 | + HIP_IFEL(!(msg = hip_msg_alloc()), -ENOMEM, "hip_msg_alloc()"); |
799 | + HIP_IFEL(hip_serialize_host_id_action(msg, ACTION_NEW, 0, 0, "rsa", |
800 | + key_path, RSA_KEY_DEFAULT_BITS, |
801 | + DSA_KEY_DEFAULT_BITS, |
802 | + ECDSA_DEFAULT_CURVE), -1, |
803 | + "Fail to create local key at %s.", key_path); |
804 | + free(msg); |
805 | + HIP_IFE(!(msg = hip_msg_alloc()), -ENOMEM); |
806 | + HIP_IFEL(hip_serialize_host_id_action(msg, ACTION_ADD, 0, 0, "rsa", |
807 | + key_path, 0, 0, 0), -1, |
808 | + "Fail to load local key at %s.", key_path); |
809 | + } |
810 | + HIP_IFE(hip_handle_add_local_hi(msg), -1); |
811 | + |
812 | +out_err: |
813 | + free(msg); |
814 | + free(key_path); |
815 | + return err; |
816 | +} |
817 | + |
818 | +/** |
819 | * create a socket to handle UDP encapsulation of HIP control |
820 | * packets |
821 | * |
822 | |
823 | === renamed file 'hipd/init.h' => 'lib/hipl/init.h' |
824 | --- hipd/init.h 2011-11-25 17:56:24 +0000 |
825 | +++ lib/hipl/init.h 2012-04-17 15:16:21 +0000 |
826 | @@ -1,5 +1,5 @@ |
827 | /* |
828 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
829 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
830 | * |
831 | * Permission is hereby granted, free of charge, to any person |
832 | * obtaining a copy of this software and associated documentation |
833 | @@ -29,6 +29,8 @@ |
834 | #include <stdint.h> |
835 | #include <netinet/in.h> |
836 | |
837 | +#include "lib/core/debug.h" |
838 | + |
839 | |
840 | /* startup flags options to be configured via the command line */ |
841 | #define HIPD_START_FOREGROUND (1 << 0) |
842 | @@ -60,4 +62,6 @@ |
843 | int is_output); |
844 | void hip_exit(void); |
845 | |
846 | +int hipl_lib_init(enum logdebug); |
847 | + |
848 | #endif /* HIPL_HIPD_INIT_H */ |
849 | |
850 | === renamed file 'hipd/input.c' => 'lib/hipl/input.c' |
851 | --- hipd/input.c 2012-04-17 11:20:20 +0000 |
852 | +++ lib/hipl/input.c 2012-04-17 15:16:21 +0000 |
853 | @@ -707,6 +707,11 @@ |
854 | &ctx->src_addr); |
855 | } |
856 | |
857 | + if (hipl_is_libhip_mode()) { |
858 | + ctx->msg_ports.src_port = ctx->hadb_entry->peer_udp_port; |
859 | + ctx->msg_ports.dst_port = ctx->hadb_entry->local_udp_port; |
860 | + } |
861 | + |
862 | hip_relay_add_rvs_to_ha(ctx->input_msg, ctx->hadb_entry); |
863 | |
864 | #ifdef CONFIG_HIP_RVS |
865 | |
866 | === renamed file 'hipd/input.h' => 'lib/hipl/input.h' |
867 | === renamed file 'hipd/keymat.c' => 'lib/hipl/keymat.c' |
868 | === renamed file 'hipd/keymat.h' => 'lib/hipl/keymat.h' |
869 | === added file 'lib/hipl/lhipl.c' |
870 | --- lib/hipl/lhipl.c 1970-01-01 00:00:00 +0000 |
871 | +++ lib/hipl/lhipl.c 2012-04-17 15:16:21 +0000 |
872 | @@ -0,0 +1,536 @@ |
873 | +/* |
874 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
875 | + * |
876 | + * Permission is hereby granted, free of charge, to any person |
877 | + * obtaining a copy of this software and associated documentation |
878 | + * files (the "Software"), to deal in the Software without |
879 | + * restriction, including without limitation the rights to use, |
880 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
881 | + * copies of the Software, and to permit persons to whom the |
882 | + * Software is furnished to do so, subject to the following |
883 | + * conditions: |
884 | + * |
885 | + * The above copyright notice and this permission notice shall be |
886 | + * included in all copies or substantial portions of the Software. |
887 | + * |
888 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
889 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
890 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
891 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
892 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
893 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
894 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
895 | + * OTHER DEALINGS IN THE SOFTWARE. |
896 | + */ |
897 | + |
898 | +/** |
899 | + * @file |
900 | + * This file contains the implementation of the libhipl public APIs. |
901 | + */ |
902 | + |
903 | +#define _BSD_SOURCE |
904 | + |
905 | +#include <errno.h> |
906 | +#include <fcntl.h> |
907 | +#include <string.h> |
908 | +#include <unistd.h> |
909 | + |
910 | +#include "lib/core/builder.h" |
911 | +#include "lib/core/ife.h" |
912 | +#include "lib/core/prefix.h" |
913 | +#include "close.h" |
914 | +#include "hadb.h" |
915 | +#include "init.h" |
916 | +#include "lhipl_sock.h" |
917 | +#include "lhipl_operations.h" |
918 | +#include "netdev.h" |
919 | +#include "output.h" |
920 | +#include "lhipl.h" |
921 | + |
922 | + |
923 | +/* A switch to turn off/on BEX feedback. |
924 | + * |
925 | + * If it is on, when the BEX process is conducted during "recvmsg" and "sendmsg", |
926 | + * the intermediate result is returned to the caller. |
927 | + * If it is off, "recvmsg" and "sendmsg" will only return after the message gets |
928 | + * sent or received. |
929 | + */ |
930 | +static bool libhipl_bex_feedback; |
931 | + |
932 | +/** |
933 | + * build a @c sockaddr_in6 address to store peer's HIT and port number from a |
934 | + * string-based peer name and a port number. |
935 | + * |
936 | + * @param peername the string representation of a peer, only support HIT string |
937 | + * currently. |
938 | + * @param port the port of the peer. |
939 | + * @param peer the @c sockaddr_in6 to hold peer's HIT and port number. |
940 | + * @return 0 on success, -1 on error. |
941 | + */ |
942 | +static int build_peer_hit(const char *peername, const uint16_t port, |
943 | + struct sockaddr_in6 *peer) |
944 | +{ |
945 | + if (!peername || !peer) { |
946 | + HIP_ERROR("Invalid input\n"); |
947 | + return -1; |
948 | + } |
949 | + |
950 | + if (inet_pton(AF_INET6, peername, &peer->sin6_addr) != 1) { |
951 | + HIP_ERROR("Failed to translate %s into HIT\n", peername); |
952 | + } |
953 | + peer->sin6_port = htons(port); |
954 | + peer->sin6_family = AF_INET6; |
955 | + return 0; |
956 | +} |
957 | + |
958 | +/** |
959 | + * Initialize libhipl library. |
960 | + * |
961 | + * This function should be called before using libhipl. |
962 | + * |
963 | + * @param debug_level the debug level of the libhipl library. |
964 | + * @return 0 on success, negative number on error. |
965 | + */ |
966 | +int hipl_lib_init_all(enum hipl_lib_loglv debug_level) |
967 | +{ |
968 | + hipl_hsock_init(); |
969 | + switch (debug_level) { |
970 | + case HIPL_LIB_LOG_DEBUG: |
971 | + return hipl_lib_init(LOGDEBUG_ALL); |
972 | + case HIPL_LIB_LOG_INFO: |
973 | + return hipl_lib_init(LOGDEBUG_MEDIUM); |
974 | + case HIPL_LIB_LOG_ERROR: |
975 | + return hipl_lib_init(LOGDEBUG_LOW); |
976 | + case HIPL_LIB_LOG_NONE: |
977 | + return hipl_lib_init(LOGDEBUG_NONE); |
978 | + } |
979 | + |
980 | + return -1; |
981 | +} |
982 | + |
983 | +/** |
984 | + * Check the current state of the BEX feedback switch. |
985 | + * |
986 | + * @return true if the switch is on, false if it is off. |
987 | + */ |
988 | +bool hipl_lib_bex_feedback(void) |
989 | +{ |
990 | + return libhipl_bex_feedback; |
991 | +} |
992 | + |
993 | +/** |
994 | + * Turn off/on the BEX feedback switch. |
995 | + * |
996 | + * @param val true to turn the switch on, false to turn it off. |
997 | + */ |
998 | +void hipl_lib_set_bex_feedback(bool val) |
999 | +{ |
1000 | + libhipl_bex_feedback = val; |
1001 | +} |
1002 | + |
1003 | +/** |
1004 | + * Turn on/off non-blocking feature for a libhipl socket. |
1005 | + * |
1006 | + * @param hsock_id ID of the libhipl socket. |
1007 | + * @param on true to turn on non-blocking, false otherwise. |
1008 | + * @return 0 on success, negative number on error. |
1009 | + */ |
1010 | +int hipl_lib_set_nonblock(const hipl_sock_id hsock_id, bool on) |
1011 | +{ |
1012 | + int flags; |
1013 | + struct hipl_sock *hsock = NULL; |
1014 | + |
1015 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1016 | + HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id); |
1017 | + return -EBADF; |
1018 | + } |
1019 | + |
1020 | + flags = fcntl(hsock->sock_fd, F_GETFL, 0); |
1021 | + if (on && !(flags & O_NONBLOCK)) { |
1022 | + fcntl(hsock->sock_fd, F_SETFL, flags | O_NONBLOCK); |
1023 | + } else if (!on && (flags & O_NONBLOCK)) { |
1024 | + fcntl(hsock->sock_fd, F_SETFL, flags & ~O_NONBLOCK); |
1025 | + } |
1026 | + return 0; |
1027 | +} |
1028 | + |
1029 | +/** |
1030 | + * Return the corresponding socket file descriptor of a libhipl socket. |
1031 | + * |
1032 | + * @param hsock_id the ID of the libhipl socket |
1033 | + * @return socket file descriptor on success, -1 on error. |
1034 | + */ |
1035 | +int hipl_lib_get_sockfd(const hipl_sock_id hsock_id) |
1036 | +{ |
1037 | + struct hipl_sock *hsock = NULL; |
1038 | + |
1039 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1040 | + HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id); |
1041 | + return -1; |
1042 | + } |
1043 | + |
1044 | + return hsock->sock_fd; |
1045 | +} |
1046 | + |
1047 | +/** |
1048 | + * Save peer's HIT-to-IP mapping. |
1049 | + * |
1050 | + * @param hit peer's hit. |
1051 | + * @param addr peer's IP address. |
1052 | + * @return 0 on success, -1 otherwise. |
1053 | + */ |
1054 | +int hipl_add_peer_info(const char *const hit, const char *const addr) |
1055 | +{ |
1056 | + struct in6_addr peer_hit, peer_addr6; |
1057 | + struct in_addr peer_addr4; |
1058 | + |
1059 | + if (!hit || !addr) { |
1060 | + HIP_ERROR("Invalid argument\n"); |
1061 | + return -1; |
1062 | + } |
1063 | + if (inet_pton(AF_INET6, hit, &peer_hit) != 1) { |
1064 | + HIP_ERROR("Invalid hit: %s\n", hit); |
1065 | + return -1; |
1066 | + } |
1067 | + if (!ipv6_addr_is_hit(&peer_hit)) { |
1068 | + HIP_ERROR("Invalid hit: %s\n", hit); |
1069 | + return -1; |
1070 | + } |
1071 | + if (inet_pton(AF_INET6, addr, &peer_addr6) != 1) { |
1072 | + if (inet_pton(AF_INET, addr, &peer_addr4) != 1) { |
1073 | + HIP_ERROR("Invalid address: %s\n", addr); |
1074 | + return -1; |
1075 | + } |
1076 | + IPV4_TO_IPV6_MAP(&peer_addr4, &peer_addr6); |
1077 | + } |
1078 | + |
1079 | + return hip_hadb_add_peer_info(&peer_hit, &peer_addr6, NULL, NULL); |
1080 | +} |
1081 | + |
1082 | +/** |
1083 | + * Create a libhipl socket. |
1084 | + * |
1085 | + * @param domain the domain of the libhipl socket (AF_INET / AF_INET6). |
1086 | + * @param type the type of the libhipl socket (SOCK_DGRAM / SOCK_STREAM). |
1087 | + * @param protocol the protocol (IPPROTO_UDP / IPPROTO_TCP). |
1088 | + * @return the ID of the new libhipl socket on success, negative |
1089 | + * number on error. |
1090 | + */ |
1091 | +int hipl_socket(const int domain, const int type, const int protocol) |
1092 | +{ |
1093 | + if (domain != AF_INET && domain != AF_INET6) { |
1094 | + HIP_ERROR("Invalid domain: %d\n", domain); |
1095 | + return -EINVAL; |
1096 | + } |
1097 | + if (type != SOCK_DGRAM && type != SOCK_STREAM) { |
1098 | + HIP_ERROR("Invalid type: %d\n", type); |
1099 | + return -EINVAL; |
1100 | + } |
1101 | + if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) { |
1102 | + HIP_ERROR("Invalid protocol: %d\n", protocol); |
1103 | + return -EINVAL; |
1104 | + } |
1105 | + |
1106 | + return hipl_socket_internal(domain, type, protocol); |
1107 | +} |
1108 | + |
1109 | +/** |
1110 | + * Close a socket. |
1111 | + * |
1112 | + * Send HIP CLOSE message to the associated peer and deletes the libhipl |
1113 | + * socket information. |
1114 | + * |
1115 | + * @param hsock_id the ID of the libhipl socket to be closed. |
1116 | + * @return 0 on success, negative number on error. |
1117 | + */ |
1118 | +int hipl_close(const hipl_sock_id hsock_id) |
1119 | +{ |
1120 | + int ret = 0; |
1121 | + struct hip_common *msg = NULL; |
1122 | + struct hipl_sock *hsock = NULL; |
1123 | + |
1124 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1125 | + HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id); |
1126 | + return -1; |
1127 | + } |
1128 | + if (!hsock->ha || hsock->ha->state == HIP_STATE_CLOSED) { |
1129 | + HIP_DEBUG("Not sending CLOSE.\n"); |
1130 | + goto skip_close_msg; |
1131 | + } |
1132 | + |
1133 | + /* Build HIP_CLOSE message and send it to the peer */ |
1134 | + if ((msg = hip_msg_alloc()) == NULL) { |
1135 | + HIP_ERROR("hip_msg_alloc() failed"); |
1136 | + ret = -ENOMEM; |
1137 | + goto skip_close_msg; |
1138 | + } |
1139 | + if ((ret = hip_build_param_contents(msg, &hsock->peer_hit, |
1140 | + HIP_PARAM_HIT, |
1141 | + sizeof(hsock->peer_hit))) < 0) { |
1142 | + HIP_ERROR("hip_build_param_contents() failed\n"); |
1143 | + goto skip_close_msg; |
1144 | + } |
1145 | + if ((ret = hip_send_close(msg, 1)) < 0) { |
1146 | + HIP_ERROR("hip_send_close() failed\n"); |
1147 | + } |
1148 | + |
1149 | +skip_close_msg: |
1150 | + if (hsock) { |
1151 | + close(hsock->sock_fd); |
1152 | + hipl_hsock_delete_and_free(hsock); |
1153 | + } |
1154 | + free(msg); |
1155 | + return ret; |
1156 | +} |
1157 | + |
1158 | +/** |
1159 | + * Bind a libhipl socket to a local IP address. |
1160 | + * |
1161 | + * @param hsock_id the ID of the libhipl socket. |
1162 | + * @param address the IP address to be bound. |
1163 | + * @param address_len the length of the @c address. |
1164 | + * @return 0 on success, negative number on error. |
1165 | + */ |
1166 | +int hipl_bind(const hipl_sock_id hsock_id, const struct sockaddr *const address, |
1167 | + const socklen_t address_len) |
1168 | +{ |
1169 | + struct hipl_sock *hsock; |
1170 | + |
1171 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1172 | + HIP_ERROR("ID %d is not a libhipl socket\n", hsock_id); |
1173 | + return -1; |
1174 | + } |
1175 | + |
1176 | + return hipl_bind_internal(hsock, address, address_len); |
1177 | +} |
1178 | + |
1179 | +/** |
1180 | + * Switch a libhipl socket to listening mode. |
1181 | + * |
1182 | + * @param hsock_id the ID of the libhipl socket. |
1183 | + * @param backlog the max length of the queue for pending connections. |
1184 | + * @return zero on success, negative number on error. |
1185 | + */ |
1186 | +int hipl_listen(const hipl_sock_id hsock_id, const int backlog) |
1187 | +{ |
1188 | + struct hipl_sock *hsock; |
1189 | + |
1190 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1191 | + HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id); |
1192 | + return -1; |
1193 | + } |
1194 | + |
1195 | + return listen(hsock->sock_fd, backlog); |
1196 | +} |
1197 | + |
1198 | +/** |
1199 | + * Send data to a peer. |
1200 | + * |
1201 | + * Triggers base exchange if no HIP association exists. |
1202 | + * @note Data is currently sent unencrypted. |
1203 | + * |
1204 | + * @param hsock_id the ID of the libhipl socket for sending data. |
1205 | + * @param msg data to send. |
1206 | + * @param len size of the data. |
1207 | + * @param flags the flags of the socket function @c sendto(). |
1208 | + * @param peername the string representation of the peer. |
1209 | + * @param port peer's port number. |
1210 | + * @return number of bytes sent on success, negative number on error. |
1211 | + */ |
1212 | +int hipl_sendto(const hipl_sock_id hsock_id, const void *const msg, |
1213 | + const size_t len, const int flags, |
1214 | + const char *const peername, uint16_t port) |
1215 | +{ |
1216 | + struct hipl_sock *hsock; |
1217 | + struct sockaddr_in6 peer; |
1218 | + struct msghdr params = { 0 }; |
1219 | + struct iovec iov; |
1220 | + char *buf = NULL; |
1221 | + int err = 0; |
1222 | + |
1223 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1224 | + HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id); |
1225 | + return -1; |
1226 | + } |
1227 | + if (hsock->sock_proto == IPPROTO_UDP |
1228 | + && (peername == NULL || build_peer_hit(peername, port, &peer) < 0)) { |
1229 | + HIP_ERROR("Invalid argument: peername\n"); |
1230 | + return -EINVAL; |
1231 | + } |
1232 | + if (hsock->sock_proto == IPPROTO_TCP |
1233 | + && hsock->peer_locator.ss_family == 0) { |
1234 | + HIP_ERROR("Not connected!\n"); |
1235 | + return -ENOTCONN; |
1236 | + } |
1237 | + if (msg == NULL) { |
1238 | + HIP_ERROR("Invalid argument: msg\n"); |
1239 | + return -EINVAL; |
1240 | + } |
1241 | + |
1242 | + struct sockaddr_storage dst; |
1243 | + struct sockaddr_in6 *p6; |
1244 | + if (hsock->sock_proto == IPPROTO_UDP) { |
1245 | + hipl_build_addrstorage(&peer.sin6_addr, ntohs(peer.sin6_port), &dst); |
1246 | + } else { |
1247 | + dst = hsock->peer_locator; |
1248 | + p6 = (struct sockaddr_in6 *) &dst; |
1249 | + p6->sin6_addr = hsock->peer_hit; |
1250 | + p6->sin6_family = AF_INET6; |
1251 | + } |
1252 | + if ((buf = malloc(len)) == NULL) { |
1253 | + return -ENOMEM; |
1254 | + } |
1255 | + memcpy(buf, msg, len); |
1256 | + iov.iov_base = buf; |
1257 | + iov.iov_len = len; |
1258 | + params.msg_name = &dst; |
1259 | + params.msg_namelen = sizeof(dst); |
1260 | + params.msg_iovlen = 1; |
1261 | + params.msg_iov = &iov; |
1262 | + |
1263 | + if (hipl_lib_bex_feedback()) { |
1264 | + err = hipl_sendmsg_internal(hsock, ¶ms, flags); |
1265 | + } else { |
1266 | + fd_set fdset; |
1267 | + if (hipl_hsock_ha_state(hsock) == HIP_STATE_UNASSOCIATED) { |
1268 | + HIP_DEBUG("Sending via hsock %d, Triggering BEX.\n", hsock->sid); |
1269 | + err = hipl_sendmsg_internal(hsock, ¶ms, flags); |
1270 | + HIP_IFEL(err != -EWAITBEX, -1, "hipl_sendmsg_internal() failed\n"); |
1271 | + } |
1272 | + if (hipl_hsock_ha_state(hsock) == HIP_STATE_ESTABLISHED) { |
1273 | + HIP_DEBUG("Sending via hsock %d, HA established.\n", hsock->sid); |
1274 | + err = hipl_sendmsg_internal(hsock, ¶ms, flags); |
1275 | + } else { |
1276 | + while (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) { |
1277 | + FD_ZERO(&fdset); |
1278 | + FD_SET(hsock->sock_fd, &fdset); |
1279 | + HIP_DEBUG("Sending via hsock %d, Waiting BEX.\n", hsock->sid); |
1280 | + err = select(hsock->sock_fd + 1, &fdset, NULL, NULL, NULL); |
1281 | + HIP_IFEL(err < 0, -1, "select(): %s\n", strerror(errno)); |
1282 | + err = hipl_sendmsg_internal(hsock, ¶ms, flags); |
1283 | + HIP_IFEL(err < 0 && err != -EWAITBEX && err != -EBEXESTABLISHED, |
1284 | + -1, "hipl_sendmsg_internal() failed\n"); |
1285 | + } |
1286 | + err = hipl_sendmsg_internal(hsock, ¶ms, flags); |
1287 | + } |
1288 | + } |
1289 | + |
1290 | +out_err: |
1291 | + free(buf); |
1292 | + return err; |
1293 | +} |
1294 | + |
1295 | +/** |
1296 | + * Receive data from a peer. |
1297 | + * |
1298 | + * Wait for base exchange if no host association exists. |
1299 | + * @note Data is currently sent unencrypted. |
1300 | + * |
1301 | + * @param hsock_id the ID of the libhipl socket for receiving data. |
1302 | + * @param buf buffer for received data. |
1303 | + * @param len the size of the @c buf. |
1304 | + * @param flags the flags of the socket function @c recvfrom(). |
1305 | + * @param peername buffer for the HIT of the associated peer, the size of |
1306 | + * this buffer should be at least @c HIPL_MAX_PEERNAME. |
1307 | + * @param port buffer for the port of the associated peer. |
1308 | + * @return number of bytes received on success, |
1309 | + * negative number on error, |
1310 | + * 0 on end-of-file. |
1311 | + */ |
1312 | +int hipl_recvfrom(const hipl_sock_id hsock_id, void *const buf, |
1313 | + const size_t len, const int flags, |
1314 | + char *const peername, uint16_t *const port) |
1315 | +{ |
1316 | + struct hipl_sock *hsock = NULL; |
1317 | + struct msghdr params = { 0 }; |
1318 | + struct iovec iov; |
1319 | + struct sockaddr_in6 hit; |
1320 | + int ret; |
1321 | + |
1322 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1323 | + HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id); |
1324 | + return -1; |
1325 | + } |
1326 | + if (hsock->sock_proto == IPPROTO_TCP |
1327 | + && hsock->peer_locator.ss_family == 0) { |
1328 | + HIP_ERROR("Not connected!\n"); |
1329 | + return -ENOTCONN; |
1330 | + } |
1331 | + |
1332 | + iov.iov_base = buf; |
1333 | + iov.iov_len = len; |
1334 | + params.msg_name = &hit; |
1335 | + params.msg_namelen = sizeof(hit); |
1336 | + params.msg_iovlen = 1; |
1337 | + params.msg_iov = &iov; |
1338 | + |
1339 | + if (!hipl_lib_bex_feedback()) { |
1340 | + fd_set fdset; |
1341 | + while (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) { |
1342 | + FD_ZERO(&fdset); |
1343 | + FD_SET(hsock->sock_fd, &fdset); |
1344 | + if (select(hsock->sock_fd + 1, &fdset, NULL, NULL, NULL) < 0) { |
1345 | + HIP_PERROR("select()"); |
1346 | + } |
1347 | + ret = hipl_recvmsg_internal(hsock, ¶ms, flags); |
1348 | + if (ret < 0 && ret != -EWAITBEX && ret != -EBEXESTABLISHED) { |
1349 | + HIP_ERROR("hipl_recvmsg_internal() failed()\n"); |
1350 | + return ret; |
1351 | + } |
1352 | + } |
1353 | + } |
1354 | + ret = hipl_recvmsg_internal(hsock, ¶ms, flags); |
1355 | + |
1356 | + if (peername) { |
1357 | + inet_ntop(AF_INET6, &hit.sin6_addr, peername, HIPL_MAX_PEERNAME); |
1358 | + } |
1359 | + if (port) { |
1360 | + *port = ntohs(hit.sin6_port); |
1361 | + } |
1362 | + return ret; |
1363 | +} |
1364 | + |
1365 | +/** |
1366 | + * Initiate a connection to a peer. |
1367 | + * |
1368 | + * @param hsock_id the ID of the libhipl socket to initiate a connection. |
1369 | + * @param peername the string representation of the peer. |
1370 | + * @param port the port number of the peer. |
1371 | + * @return 0 on success, negative number on error. |
1372 | + */ |
1373 | +int hipl_connect(const hipl_sock_id hsock_id, const char *peername, |
1374 | + const uint16_t port) |
1375 | +{ |
1376 | + struct hipl_sock *hsock = NULL; |
1377 | + struct sockaddr_in6 peer; |
1378 | + |
1379 | + if (peername == NULL || build_peer_hit(peername, port, &peer) < 0) { |
1380 | + HIP_ERROR("Invalid argument: peername\n"); |
1381 | + return -EINVAL; |
1382 | + } |
1383 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1384 | + HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id); |
1385 | + return -1; |
1386 | + } |
1387 | + |
1388 | + return hipl_connect_internal(hsock, &peer); |
1389 | +} |
1390 | + |
1391 | +/** |
1392 | + * Wait for an incoming connection. |
1393 | + * |
1394 | + * @param hsock_id the ID of the libhipl socket for waiting connections. |
1395 | + * @return the ID of the accepted libhipl socket, negative number |
1396 | + * on error. |
1397 | + */ |
1398 | +int hipl_accept(const hipl_sock_id hsock_id) |
1399 | +{ |
1400 | + struct hipl_sock *hsock = NULL; |
1401 | + |
1402 | + if ((hsock = hipl_hsock_find(hsock_id)) == NULL) { |
1403 | + HIP_ERROR("ID %d is not a libhipl socket.\n", hsock_id); |
1404 | + return -1; |
1405 | + } |
1406 | + |
1407 | + return hipl_accept_internal(hsock); |
1408 | +} |
1409 | |
1410 | === added file 'lib/hipl/lhipl.h' |
1411 | --- lib/hipl/lhipl.h 1970-01-01 00:00:00 +0000 |
1412 | +++ lib/hipl/lhipl.h 2012-04-17 15:16:21 +0000 |
1413 | @@ -0,0 +1,76 @@ |
1414 | +/* |
1415 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
1416 | + * |
1417 | + * Permission is hereby granted, free of charge, to any person |
1418 | + * obtaining a copy of this software and associated documentation |
1419 | + * files (the "Software"), to deal in the Software without |
1420 | + * restriction, including without limitation the rights to use, |
1421 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
1422 | + * copies of the Software, and to permit persons to whom the |
1423 | + * Software is furnished to do so, subject to the following |
1424 | + * conditions: |
1425 | + * |
1426 | + * The above copyright notice and this permission notice shall be |
1427 | + * included in all copies or substantial portions of the Software. |
1428 | + * |
1429 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
1430 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
1431 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
1432 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
1433 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
1434 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
1435 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
1436 | + * OTHER DEALINGS IN THE SOFTWARE. |
1437 | + */ |
1438 | + |
1439 | +#ifndef HIPL_LIB_HIPL_LHIPL_H |
1440 | +#define HIPL_LIB_HIPL_LHIPL_H |
1441 | + |
1442 | +#include <sys/socket.h> |
1443 | +#include <stdbool.h> |
1444 | +#include <stdint.h> |
1445 | + |
1446 | + |
1447 | +#define EWAITBEX 139000 |
1448 | +#define EBEXESTABLISHED 139001 |
1449 | + |
1450 | +#define HIPL_MAX_PEERNAME 128 |
1451 | + |
1452 | +enum hipl_lib_loglv { HIPL_LIB_LOG_DEBUG, HIPL_LIB_LOG_INFO, |
1453 | + HIPL_LIB_LOG_ERROR, HIPL_LIB_LOG_NONE }; |
1454 | + |
1455 | +typedef uint16_t hipl_sock_id; |
1456 | + |
1457 | +int hipl_lib_init_all(enum hipl_lib_loglv); |
1458 | + |
1459 | +void hipl_lib_set_bex_feedback(bool val); |
1460 | +bool hipl_lib_bex_feedback(void); |
1461 | + |
1462 | +int hipl_lib_set_nonblock(const hipl_sock_id hsock_id, bool on); |
1463 | +int hipl_lib_get_sockfd(const hipl_sock_id hsock_id); |
1464 | + |
1465 | +int hipl_add_peer_info(const char *const hit, const char *const addr); |
1466 | + |
1467 | +int hipl_socket(const int domain, const int type, const int protocol); |
1468 | + |
1469 | +int hipl_close(const hipl_sock_id hsock_id); |
1470 | + |
1471 | +int hipl_listen(const hipl_sock_id hsock_id, const int backlog); |
1472 | + |
1473 | +int hipl_bind(const hipl_sock_id hsock_id, const struct sockaddr *const address, |
1474 | + const socklen_t address_len); |
1475 | + |
1476 | +int hipl_sendto(const hipl_sock_id hsock_id, const void *const msg, |
1477 | + const size_t len, const int flags, |
1478 | + const char *const peername, const uint16_t port); |
1479 | + |
1480 | +int hipl_recvfrom(const hipl_sock_id hsock_id, void *const buf, |
1481 | + const size_t len, const int flags, |
1482 | + char *const peername, uint16_t *const port); |
1483 | + |
1484 | +int hipl_connect(const hipl_sock_id hsock_id, const char *const peername, |
1485 | + const uint16_t port); |
1486 | + |
1487 | +int hipl_accept(const hipl_sock_id hsock_id); |
1488 | + |
1489 | +#endif /* HIPL_LIB_HIPL_LHIPL_H */ |
1490 | |
1491 | === added file 'lib/hipl/lhipl_operations.c' |
1492 | --- lib/hipl/lhipl_operations.c 1970-01-01 00:00:00 +0000 |
1493 | +++ lib/hipl/lhipl_operations.c 2012-04-17 15:16:21 +0000 |
1494 | @@ -0,0 +1,771 @@ |
1495 | +/* |
1496 | + * Copyright (c) 2012 Aalto University and RWTH Aachen University. |
1497 | + * |
1498 | + * Permission is hereby granted, free of charge, to any person |
1499 | + * obtaining a copy of this software and associated documentation |
1500 | + * files (the "Software"), to deal in the Software without |
1501 | + * restriction, including without limitation the rights to use, |
1502 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
1503 | + * copies of the Software, and to permit persons to whom the |
1504 | + * Software is furnished to do so, subject to the following |
1505 | + * conditions: |
1506 | + * |
1507 | + * The above copyright notice and this permission notice shall be |
1508 | + * included in all copies or substantial portions of the Software. |
1509 | + * |
1510 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
1511 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
1512 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
1513 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
1514 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
1515 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
1516 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
1517 | + * OTHER DEALINGS IN THE SOFTWARE. |
1518 | + */ |
1519 | + |
1520 | +/** |
1521 | + * @file |
1522 | + * This file contains the internal implementation of the libhipl socket |
1523 | + * related operations. |
1524 | + */ |
1525 | + |
1526 | +#define _BSD_SOURCE |
1527 | + |
1528 | +#include <sys/socket.h> |
1529 | +#include <errno.h> |
1530 | +#include <fcntl.h> |
1531 | +#include <stdbool.h> |
1532 | +#include <string.h> |
1533 | +#include <unistd.h> |
1534 | + |
1535 | +#include "lib/core/builder.h" |
1536 | +#include "lib/core/hip_udp.h" |
1537 | +#include "lib/core/ife.h" |
1538 | +#include "lib/core/prefix.h" |
1539 | +#include "lhipl.h" |
1540 | +#include "lhipl_sock.h" |
1541 | +#include "hadb.h" |
1542 | +#include "hidb.h" |
1543 | +#include "input.h" |
1544 | +#include "netdev.h" |
1545 | +#include "output.h" |
1546 | +#include "lhipl_operations.h" |
1547 | + |
1548 | + |
1549 | +/** |
1550 | + * Automatically bind to a port for a libhipl socket. |
1551 | + * |
1552 | + * @param hsock the libhipl socket for port binding. |
1553 | + * @return 0 on success, -1 on error. |
1554 | + */ |
1555 | +static int auto_bind(struct hipl_sock *const hsock) |
1556 | +{ |
1557 | + struct sockaddr_storage ss = { 0 }; |
1558 | + struct sockaddr_in *addr4; |
1559 | + struct sockaddr_in6 *addr6; |
1560 | + |
1561 | + if (hsock->src_port != 0) { |
1562 | + HIP_DEBUG("A bound port exists, auto_bind stops\n"); |
1563 | + return 0; |
1564 | + } |
1565 | + |
1566 | + if (hsock->sock_family == AF_INET) { |
1567 | + ss.ss_family = AF_INET; |
1568 | + addr4 = (struct sockaddr_in *) &ss; |
1569 | + addr4->sin_port = 0; |
1570 | + return hipl_bind_internal(hsock, (struct sockaddr *) addr4, |
1571 | + sizeof(ss)); |
1572 | + } else { |
1573 | + ss.ss_family = AF_INET6; |
1574 | + addr6 = (struct sockaddr_in6 *) &ss; |
1575 | + addr6->sin6_port = 0; |
1576 | + return hipl_bind_internal(hsock, (struct sockaddr *) addr6, |
1577 | + sizeof(ss)); |
1578 | + } |
1579 | +} |
1580 | + |
1581 | +static uint16_t get_port_from_saddr(const struct sockaddr *const addr) |
1582 | +{ |
1583 | + const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr; |
1584 | + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr; |
1585 | + |
1586 | + if (addr->sa_family == AF_INET) { |
1587 | + return addr4->sin_port; |
1588 | + } else { |
1589 | + return addr6->sin6_port; |
1590 | + } |
1591 | +} |
1592 | + |
1593 | +/** |
1594 | + * Set global variables in order to inter-operate with libhipdeamon. |
1595 | + * |
1596 | + * @param sock_fd the socket file descriptor for sending message. |
1597 | + * @param local_port the local port for sending message. |
1598 | + * @param remote_port the remote port for receiving message. |
1599 | + */ |
1600 | +static void set_hip_connection_parameters(const int sock_fd, |
1601 | + const int local_port, |
1602 | + const int remote_port) |
1603 | +{ |
1604 | + HIP_DEBUG("Set connection params: fd = %d, lport = %d, rport= %d\n", |
1605 | + sock_fd, local_port, remote_port); |
1606 | + hip_nat_sock_output_udp = sock_fd; |
1607 | + hip_raw_sock_output_v4 = sock_fd; |
1608 | + hip_raw_sock_output_v6 = sock_fd; |
1609 | + hip_set_local_nat_udp_port(local_port); |
1610 | + hip_set_peer_nat_udp_port(remote_port); |
1611 | +} |
1612 | + |
1613 | +/** |
1614 | + * Check whether a received packet is a HIP control packet. |
1615 | + * |
1616 | + * @param buf buffer containing the received packet. |
1617 | + * @param len size of the @c buf. |
1618 | + * @param hsock the libhipl socket receiving the packet. |
1619 | + * @return 1 on a control message, 0 on a user message, |
1620 | + * negative number on error. |
1621 | + */ |
1622 | +static int hipl_is_control_msg(char *const buf, unsigned int len, |
1623 | + struct hipl_sock *const hsock) |
1624 | +{ |
1625 | + char udp_pad[HIP_UDP_ZERO_BYTES_LEN] = { 0 }; |
1626 | + struct hip_common *msg; |
1627 | + struct sockaddr_storage src = { 0 }; |
1628 | + socklen_t srclen = sizeof(src); |
1629 | + |
1630 | + if (len < sizeof(struct hip_common)) { |
1631 | + return 0; |
1632 | + } |
1633 | + |
1634 | + if (!memcmp(udp_pad, buf, HIP_UDP_ZERO_BYTES_LEN)) { |
1635 | + HIP_DEBUG("Message is padded\n"); |
1636 | + msg = (struct hip_common *) (buf + HIP_UDP_ZERO_BYTES_LEN); |
1637 | + len -= HIP_UDP_ZERO_BYTES_LEN; |
1638 | + } else { |
1639 | + msg = (struct hip_common *) buf; |
1640 | + } |
1641 | + |
1642 | + if (getsockname(hsock->sock_fd, (struct sockaddr *) &src, &srclen) < 0) { |
1643 | + HIP_PERROR("getsockname()"); |
1644 | + return true; |
1645 | + } |
1646 | + |
1647 | + return !hip_verify_network_header(msg, (struct sockaddr *) &src, |
1648 | + (struct sockaddr *) &hsock->peer_locator, |
1649 | + len); |
1650 | +} |
1651 | + |
1652 | +static void build_packet_context(struct hip_packet_context *const ctx, |
1653 | + struct sockaddr *ctx_dst, struct sockaddr *ctx_src) |
1654 | +{ |
1655 | + struct sockaddr_in *s4; |
1656 | + struct sockaddr_in6 *s6; |
1657 | + |
1658 | + if (ctx_dst->sa_family == AF_INET) { |
1659 | + s4 = (struct sockaddr_in *) ctx_dst; |
1660 | + IPV4_TO_IPV6_MAP(&s4->sin_addr, &ctx->dst_addr); |
1661 | + ctx->msg_ports.dst_port = ntohs(s4->sin_port); |
1662 | + } else if (ctx_dst->sa_family == AF_INET6) { |
1663 | + s6 = (struct sockaddr_in6 *) ctx_dst; |
1664 | + ctx->dst_addr = s6->sin6_addr; |
1665 | + ctx->msg_ports.dst_port = ntohs(s6->sin6_port); |
1666 | + } |
1667 | + |
1668 | + if (ctx_src->sa_family == AF_INET) { |
1669 | + s4 = (struct sockaddr_in *) ctx_src; |
1670 | + IPV4_TO_IPV6_MAP(&s4->sin_addr, &ctx->src_addr); |
1671 | + ctx->msg_ports.src_port = ntohs(s4->sin_port); |
1672 | + } else if (ctx_src->sa_family == AF_INET6) { |
1673 | + s6 = (struct sockaddr_in6 *) ctx_src; |
1674 | + ctx->src_addr = s6->sin6_addr; |
1675 | + ctx->msg_ports.src_port = ntohs(s6->sin6_port); |
1676 | + } |
1677 | +} |
1678 | + |
1679 | +/** |
1680 | + * Receive and pre-process an incoming message. |
1681 | + * |
1682 | + * This function discards UDP packet from an unknown peer, identifies |
1683 | + * user/control packet, eliminates zero padding in control packets and |
1684 | + * builds the packet context for handling control packets. |
1685 | + * |
1686 | + * @param hsock the libhipl socket for receiving message. |
1687 | + * @param msg buffer to hold the incoming message. |
1688 | + * @param flags the flags of socket @c recvmsg(). |
1689 | + * @param ctx the HIP packet context to be built. |
1690 | + * @param is_user_msg true if the message is a user message, false otherwise. |
1691 | + * @return negative number on errors, 0 on end-of-file, number of |
1692 | + * bytes received otherwise. |
1693 | + */ |
1694 | +static int recv_msg_wrapper(struct hipl_sock *const hsock, |
1695 | + struct msghdr *const msg, const int flags, |
1696 | + struct hip_packet_context *const ctx, |
1697 | + bool *is_user_msg) |
1698 | +{ |
1699 | + int ret; |
1700 | + struct sockaddr_storage our_locator = { 0 }; |
1701 | + socklen_t sslen = sizeof(our_locator); |
1702 | + |
1703 | + *is_user_msg = true; |
1704 | + if ((ret = recvmsg(hsock->sock_fd, msg, flags)) < 0) { |
1705 | + HIP_PERROR("recvmsg()"); |
1706 | + return -1; |
1707 | + } |
1708 | + |
1709 | + //in UDP mode, we don't know the peer locator until we receive the |
1710 | + //first message from the peer. Once we get the peer locator, save it |
1711 | + //to 'hsock'. We should also fill the packet context for UDP. |
1712 | + if (hsock->sock_proto == IPPROTO_UDP) { |
1713 | + if (msg->msg_name != NULL && hsock->peer_locator.ss_family == 0) { |
1714 | + memcpy(&hsock->peer_locator, msg->msg_name, |
1715 | + sizeof(hsock->peer_locator)); |
1716 | + } |
1717 | + if (ctx != NULL) { |
1718 | + if (getsockname(hsock->sock_fd, (struct sockaddr *) &our_locator, |
1719 | + &sslen) < 0) { |
1720 | + HIP_PERROR("getsockname()"); |
1721 | + return -1; |
1722 | + } |
1723 | + build_packet_context(ctx, (struct sockaddr *) &our_locator, |
1724 | + (struct sockaddr *) &hsock->peer_locator); |
1725 | + } |
1726 | + } |
1727 | + |
1728 | + char *buf = (char *) msg->msg_iov->iov_base; |
1729 | + if (hipl_is_control_msg(buf, ret, hsock)) { |
1730 | + memmove(buf, buf + HIP_UDP_ZERO_BYTES_LEN, |
1731 | + HIP_MAX_PACKET - HIP_UDP_ZERO_BYTES_LEN); |
1732 | + ret -= HIP_UDP_ZERO_BYTES_LEN; |
1733 | + *is_user_msg = false; |
1734 | + } |
1735 | + |
1736 | + return ret; |
1737 | +} |
1738 | + |
1739 | +static int nonb_result_check(const int ret, const int err) |
1740 | +{ |
1741 | + if (ret < 0 && err != EWOULDBLOCK && err != EAGAIN) { |
1742 | + HIP_ERROR("BEX failed, errno = %d, errstr = %s\n", err, |
1743 | + strerror(err)); |
1744 | + return -1; |
1745 | + } |
1746 | + if (ret < 0 && (err == EWOULDBLOCK || err == EAGAIN)) { |
1747 | + HIP_DEBUG("BEX returns EWOULDBLOCK or EAGAIN\n"); |
1748 | + return -EWAITBEX; |
1749 | + } |
1750 | + |
1751 | + return 0; |
1752 | +} |
1753 | + |
1754 | +/** |
1755 | + * Wait for a HIP I1 packet and continue performing base exchange. |
1756 | + * |
1757 | + * @param hsock the libhipl socket waiting for the I1 packet. |
1758 | + * @param ctx the HIP packet context for HIP packet processing. |
1759 | + * @return 0 on success, -1 on error, -EWAITBEX when BEX is pending |
1760 | + */ |
1761 | +static int nonb_await_bex(struct hipl_sock *const hsock, |
1762 | + struct hip_packet_context *const ctx) |
1763 | +{ |
1764 | + struct msghdr params = { 0 }; |
1765 | + struct iovec iov; |
1766 | + struct sockaddr_storage ss; |
1767 | + bool is_user_msg; |
1768 | + int ret = 0; |
1769 | + int flag; |
1770 | + |
1771 | + params.msg_name = &ss; |
1772 | + params.msg_namelen = sizeof(ss); |
1773 | + params.msg_iovlen = 1; |
1774 | + iov.iov_base = ctx->input_msg; |
1775 | + iov.iov_len = HIP_MAX_PACKET; |
1776 | + params.msg_iov = &iov; |
1777 | + |
1778 | + flag = fcntl(hsock->sock_fd, F_GETFL, 0); |
1779 | + fcntl(hsock->sock_fd, F_SETFL, flag | O_NONBLOCK); |
1780 | + |
1781 | + set_hip_connection_parameters(hsock->sock_fd, hsock->src_port, 0); |
1782 | + ret = recv_msg_wrapper(hsock, ¶ms, 0, ctx, &is_user_msg); |
1783 | + if ((ret = nonb_result_check(ret, errno)) != 0) { |
1784 | + HIP_DEBUG("returns %d\n", ret); |
1785 | + goto out; |
1786 | + } |
1787 | + |
1788 | + if (is_user_msg || hip_receive_control_packet(ctx) < 0) { |
1789 | + HIP_ERROR("hip_receive_control_packet() failed\n"); |
1790 | + ret = -1; |
1791 | + } |
1792 | + |
1793 | +out: |
1794 | + fcntl(hsock->sock_fd, F_SETFL, flag); |
1795 | + return ret; |
1796 | +} |
1797 | + |
1798 | +/** |
1799 | + * Trigger BEX in a non-blocking way. |
1800 | + * |
1801 | + * @param hsock the libhipl socket to trigger BEX. |
1802 | + * @param src_hit the source HIT for base exchange. |
1803 | + * @param dst_hit the destination HIT for base exchange. |
1804 | + * @param dst_port the destination port. |
1805 | + * @return -1 on error, -EWAITBEX when the BEX is pending, 0 if sending |
1806 | + * BEX trigger message successfully. |
1807 | + */ |
1808 | +static int nonb_trigger_bex(struct hipl_sock *hsock, const hip_hit_t *src_hit, |
1809 | + const hip_hit_t *dst_hit, const int dst_port) |
1810 | +{ |
1811 | + struct in6_addr dst_addr; |
1812 | + int err = 0, flag; |
1813 | + |
1814 | + flag = fcntl(hsock->sock_fd, F_GETFL, 0); |
1815 | + fcntl(hsock->sock_fd, F_SETFL, flag | O_NONBLOCK); |
1816 | + |
1817 | + err = hip_map_id_to_addr(dst_hit, NULL, &dst_addr); |
1818 | + HIP_IFEL(err < 0, -1, "failed to match hit to IP\n"); |
1819 | + HIP_IFEL(ipv6_addr_any(&dst_addr), -1, "Couldn't map HIT to IP\n"); |
1820 | + |
1821 | + set_hip_connection_parameters(hsock->sock_fd, hsock->src_port, dst_port); |
1822 | + err = netdev_trigger_bex(src_hit, dst_hit, NULL, NULL, NULL, &dst_addr); |
1823 | + HIP_DEBUG("netdev_trigger_bex returns %d, errno = %d\n", err, errno); |
1824 | + err = nonb_result_check(err, errno); |
1825 | + if (err == 0) { |
1826 | + hsock->ha = hip_hadb_find_byhits(src_hit, dst_hit); |
1827 | + } |
1828 | + |
1829 | +out_err: |
1830 | + fcntl(hsock->sock_fd, F_SETFL, flag); |
1831 | + return err; |
1832 | +} |
1833 | + |
1834 | +/** |
1835 | + * Handle BEX for a libhipl socket. |
1836 | + * |
1837 | + * If param @c peer_hit is given, current libhipl socket will be the initiator |
1838 | + * and trigger the BEX. otherwise, it acts as a responder and waits for an I1 |
1839 | + * message. |
1840 | + * |
1841 | + * @param hsock the libhipl socket to handle BEX. |
1842 | + * @param peer_hit the peer's hit and port. |
1843 | + * @return -1 on error, -EWAITBEX when the BEX is pending, and |
1844 | + * -EBEXESTABLISHED when BEX finishes. |
1845 | + */ |
1846 | +static int handle_bex(struct hipl_sock *hsock, struct sockaddr_in6 *peer_hit) |
1847 | +{ |
1848 | + int err = 0; |
1849 | + struct hip_packet_context ctx = { 0 }; |
1850 | + |
1851 | + // We are the initiator, send I1 |
1852 | + if (hipl_hsock_ha_state(hsock) == HIP_STATE_UNASSOCIATED && peer_hit) { |
1853 | + hsock->peer_hit = peer_hit->sin6_addr; |
1854 | + |
1855 | + err = nonb_trigger_bex(hsock, &hsock->src_hit, &peer_hit->sin6_addr, |
1856 | + ntohs(peer_hit->sin6_port)); |
1857 | + // send I1 successfully, return -EWAITBEX. |
1858 | + if (err == 0) { |
1859 | + err = -EWAITBEX; |
1860 | + } |
1861 | + return err; |
1862 | + } |
1863 | + |
1864 | + // waiting for and handle control messages |
1865 | + hsock->ha = hip_hadb_find_byhits(&hsock->src_hit, &hsock->peer_hit); |
1866 | + if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) { |
1867 | + ctx.input_msg = hip_msg_alloc(); |
1868 | + ctx.output_msg = hip_msg_alloc(); |
1869 | + HIP_IFEL(!ctx.input_msg || !ctx.output_msg, -ENOMEM, |
1870 | + "hip_msg_alloc() failed\n"); |
1871 | + |
1872 | + err = nonb_await_bex(hsock, &ctx); |
1873 | + HIP_DEBUG("nonb_await_bex returns %d\n", err); |
1874 | + if (err < 0) { /* -1 or -EWAITBEX */ |
1875 | + goto out_err; |
1876 | + } |
1877 | + hsock->peer_hit = ctx.input_msg->hit_sender; |
1878 | + hsock->ha = hip_hadb_find_byhits(&hsock->src_hit, &hsock->peer_hit); |
1879 | + } |
1880 | + |
1881 | + if (hipl_hsock_ha_state(hsock) == HIP_STATE_ESTABLISHED) { |
1882 | + err = -EBEXESTABLISHED; |
1883 | + } else { |
1884 | + err = -EWAITBEX; |
1885 | + } |
1886 | + |
1887 | +out_err: |
1888 | + free(ctx.input_msg); |
1889 | + free(ctx.output_msg); |
1890 | + return err; |
1891 | +} |
1892 | + |
1893 | +static int validate_udp_peer_addr(const struct hipl_sock *const hsock, |
1894 | + const struct sockaddr_storage *const saddr) |
1895 | +{ |
1896 | + const struct in6_addr *paddr; |
1897 | + struct in6_addr peer_addr; |
1898 | + |
1899 | + if (hsock->sock_proto != IPPROTO_UDP) { |
1900 | + return 0; |
1901 | + } |
1902 | + |
1903 | + switch (saddr->ss_family) { |
1904 | + case AF_INET: |
1905 | + IPV4_TO_IPV6_MAP(&((const struct sockaddr_in *) saddr)->sin_addr, |
1906 | + &peer_addr); |
1907 | + paddr = &peer_addr; |
1908 | + break; |
1909 | + |
1910 | + case AF_INET6: |
1911 | + paddr = &((const struct sockaddr_in6 *) saddr)->sin6_addr; |
1912 | + break; |
1913 | + |
1914 | + default: |
1915 | + HIP_DEBUG("Unsupported family: %d\n", saddr->ss_family); |
1916 | + return -1; |
1917 | + } |
1918 | + |
1919 | + if (ipv6_addr_cmp(&hsock->ha->peer_addr, paddr)) { |
1920 | + HIP_DEBUG("Packet not from associated address. Dropping.\n"); |
1921 | + HIP_DEBUG_IN6ADDR("expected", &hsock->ha->peer_addr); |
1922 | + HIP_DEBUG_IN6ADDR("got", paddr); |
1923 | + return -1; |
1924 | + } |
1925 | + |
1926 | + return 0; |
1927 | +} |
1928 | + |
1929 | +/** |
1930 | + * Build a @c sockaddr_storage from a given IPv6 address and a port number. |
1931 | + * |
1932 | + * If the address is V4MAPPED, the storage family will be @c AF_INET, |
1933 | + * otherwise the storage family will be @c AF_INET6. |
1934 | + * |
1935 | + * @param addr a V6 address or a V4MAPPED address. |
1936 | + * @param port the port number. |
1937 | + * @param ss the @c sockaddr_storage to be filled. |
1938 | + */ |
1939 | +void hipl_build_addrstorage(const struct in6_addr *const addr, |
1940 | + const uint16_t port, |
1941 | + struct sockaddr_storage *const ss) |
1942 | +{ |
1943 | + HIP_ASSERT(addr && ss); |
1944 | + memset(ss, 0, sizeof(*ss)); |
1945 | + |
1946 | + if (IN6_IS_ADDR_V4MAPPED(addr)) { |
1947 | + struct sockaddr_in *const in = (struct sockaddr_in *) ss; |
1948 | + in->sin_family = AF_INET; |
1949 | + IPV6_TO_IPV4_MAP(addr, &in->sin_addr); |
1950 | + in->sin_port = htons(port); |
1951 | + } else { |
1952 | + struct sockaddr_in6 *const in6 = (struct sockaddr_in6 *) ss; |
1953 | + in6->sin6_family = AF_INET6; |
1954 | + ipv6_addr_copy(&in6->sin6_addr, addr); |
1955 | + in6->sin6_port = htons(port); |
1956 | + } |
1957 | +} |
1958 | + |
1959 | +/** |
1960 | + * Create a libhipl socket. |
1961 | + * |
1962 | + * @param family the communications domain of the libhipl socket |
1963 | + * @param type the socket type of the libhipl socket |
1964 | + * @param protocol the protocol of the libhipl socket |
1965 | + * @return the ID of the new libhipl socket on success, negative |
1966 | + * number otherwise |
1967 | + */ |
1968 | +int hipl_socket_internal(const int family, const int type, const int protocol) |
1969 | +{ |
1970 | + int sock; |
1971 | + int on = 1, off = 0; |
1972 | + struct hipl_sock *hsock = NULL; |
1973 | + |
1974 | + //TODO support IPV6 |
1975 | + if (family == AF_INET6) { |
1976 | + HIP_ERROR("No IPv6 support yet.\n"); |
1977 | + return -ENOTSUP; |
1978 | + } |
1979 | + |
1980 | + sock = socket(family, type, protocol); |
1981 | + if (family == AF_INET) { |
1982 | + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); |
1983 | + setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); |
1984 | + setsockopt(sock, IPPROTO_IP, IP_RECVERR, &off, sizeof(off)); |
1985 | + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
1986 | + } else { |
1987 | + setsockopt(sock, IPPROTO_IPV6, IPV6_RECVERR, &off, sizeof(off)); |
1988 | + setsockopt(sock, IPPROTO_IPV6, IPV6_2292PKTINFO, &on, sizeof(on)); |
1989 | + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
1990 | + } |
1991 | + if ((hsock = hipl_hsock_new(family, type, protocol)) == NULL) { |
1992 | + HIP_ERROR("Failed to create libhipl socket.\n"); |
1993 | + close(sock); |
1994 | + return -1; |
1995 | + } |
1996 | + hsock->sock_fd = sock; |
1997 | + hip_get_default_hit(&hsock->src_hit); |
1998 | + |
1999 | + return hsock->sid; |
2000 | +} |
2001 | + |
2002 | +/** |
2003 | + * Bind a libhipl socket to a local address. |
2004 | + * |
2005 | + * @param hsock the libhipl socket for address binding. |
2006 | + * @param address the IP address to be bound. |
2007 | + * @param address_len the length of the @c address. |
2008 | + * @return 0 on success, -1 on error. |
2009 | + */ |
2010 | +int hipl_bind_internal(struct hipl_sock *const hsock, |
2011 | + const struct sockaddr *const address, |
2012 | + const socklen_t address_len) |
2013 | +{ |
2014 | + struct sockaddr_storage laddr = { 0 }; |
2015 | + socklen_t laddr_len = sizeof(laddr); |
2016 | + uint16_t request_port; |
2017 | + |
2018 | + request_port = get_port_from_saddr(address); |
2019 | + if (bind(hsock->sock_fd, address, address_len) < 0) { |
2020 | + HIP_PERROR("bind error:"); |
2021 | + return -1; |
2022 | + } |
2023 | + |
2024 | + /* Ask OS for the assigned port number */ |
2025 | + if (request_port == 0) { |
2026 | + if (0 > getsockname(hsock->sock_fd, (struct sockaddr *) &laddr, |
2027 | + &laddr_len)) { |
2028 | + HIP_PERROR("getsockname() error: "); |
2029 | + return -1; |
2030 | + } |
2031 | + request_port = get_port_from_saddr((struct sockaddr *) &laddr); |
2032 | + } |
2033 | + |
2034 | + hsock->src_port = ntohs(request_port); |
2035 | + HIP_DEBUG("bind to port %d\n", hsock->src_port); |
2036 | + |
2037 | + return 0; |
2038 | +} |
2039 | + |
2040 | +/** |
2041 | + * Initiate a connection to a peer. |
2042 | + * |
2043 | + * @param hsock the libhipl socket to initiate the connection. |
2044 | + * @param peer the peer's HIT and port number. |
2045 | + * @return 0 on success, -1 on error. |
2046 | + */ |
2047 | +int hipl_connect_internal(struct hipl_sock *const hsock, |
2048 | + const struct sockaddr_in6 *const peer) |
2049 | +{ |
2050 | + struct in6_addr dst_addr = { { { 0 } } }; |
2051 | + struct sockaddr_storage ss; |
2052 | + |
2053 | + if (ipv6_addr_any(&peer->sin6_addr)) { |
2054 | + HIP_ERROR("Invalid argument: dst_hit.\n"); |
2055 | + return -1; |
2056 | + } |
2057 | + |
2058 | + if (hip_map_id_to_addr(&peer->sin6_addr, NULL, &dst_addr) < 0) { |
2059 | + return -1; |
2060 | + } |
2061 | + if (ipv6_addr_any(&dst_addr)) { |
2062 | + HIP_ERROR("Couldn't map HIT to IP\n"); |
2063 | + return -1; |
2064 | + } |
2065 | + |
2066 | + HIP_DEBUG_IN6ADDR("Dest locator is: ", &dst_addr); |
2067 | + HIP_DEBUG("Dest locator is V4MAPPED: %d\n", IN6_IS_ADDR_V4MAPPED(&dst_addr)); |
2068 | + hipl_build_addrstorage(&dst_addr, ntohs(peer->sin6_port), &ss); |
2069 | + |
2070 | + if (connect(hsock->sock_fd, (struct sockaddr *) &ss, sizeof(ss)) < 0) { |
2071 | + HIP_ERROR("connect(): %s\n", strerror(errno)); |
2072 | + return -1; |
2073 | + } |
2074 | + |
2075 | + /* Save related information into hsock */ |
2076 | + hsock->peer_hit = peer->sin6_addr; |
2077 | + hsock->peer_locator = ss; |
2078 | + if (hsock->src_port == 0) { |
2079 | + socklen_t taddr_len = sizeof(ss); |
2080 | + |
2081 | + if (getsockname(hsock->sock_fd, (struct sockaddr *) &ss, |
2082 | + &taddr_len) < 0) { |
2083 | + HIP_PERROR("getsockname() error: "); |
2084 | + return -1; |
2085 | + } |
2086 | + hsock->src_port = ntohs(get_port_from_saddr((struct sockaddr *) &ss)); |
2087 | + } |
2088 | + |
2089 | + return 0; |
2090 | +} |
2091 | + |
2092 | +/** |
2093 | + * Wait for an incoming connection on a libhipl socket. |
2094 | + * |
2095 | + * @param hsock the libhipl socket waiting for the connection. |
2096 | + * @return the ID of the accepted libhipl socket on success, -1 on error. |
2097 | + */ |
2098 | +int hipl_accept_internal(struct hipl_sock *const hsock) |
2099 | +{ |
2100 | + int new_fd; |
2101 | + struct hipl_sock *hsock_new = NULL; |
2102 | + struct sockaddr_storage ss = { 0 }; |
2103 | + socklen_t ss_len = sizeof(ss); |
2104 | + |
2105 | + new_fd = accept(hsock->sock_fd, (struct sockaddr *) &ss, &ss_len); |
2106 | + if (new_fd < 0) { |
2107 | + HIP_PERROR("accept(): "); |
2108 | + return -1; |
2109 | + } |
2110 | + |
2111 | + hsock_new = hipl_hsock_new(hsock->sock_family, hsock->sock_type, |
2112 | + hsock->sock_proto); |
2113 | + hsock_new->src_port = hsock->src_port; |
2114 | + hsock_new->src_hit = hsock->src_hit; |
2115 | + hsock_new->sock_fd = new_fd; |
2116 | + hsock_new->peer_locator = ss; |
2117 | + |
2118 | + return hsock_new->sid; |
2119 | +} |
2120 | + |
2121 | +/** |
2122 | + * Receive data from a remote peer. |
2123 | + * |
2124 | + * Wait for base exchange if no host association exists. |
2125 | + * @note Data is currently sent unencrypted. |
2126 | + * @note Scatter read is not supported yet. |
2127 | + * |
2128 | + * @param hsock the libhipl socket for receiving data. |
2129 | + * @param msg the buffer to hold data and peer information. |
2130 | + * @param flags the flags of the socket function @c recvmsg(). |
2131 | + * @return number of bytes received on success, |
2132 | + * 0 on end-of-file, |
2133 | + * -EWAITBEX when the BEX is pending, |
2134 | + * -EBEXESTABLISHED when BEX finishes, |
2135 | + * other negative numbers on error. |
2136 | + */ |
2137 | +ssize_t hipl_recvmsg_internal(struct hipl_sock *const hsock, |
2138 | + struct msghdr *const msg, |
2139 | + const int flags) |
2140 | +{ |
2141 | + struct hip_packet_context ctx = { 0 }; |
2142 | + struct msghdr params = { 0 }; |
2143 | + struct iovec iov; |
2144 | + struct sockaddr_storage recv_remote_addr; |
2145 | + int err = 0; |
2146 | + bool is_user_msg; |
2147 | + |
2148 | + if (msg->msg_iovlen != 1) { |
2149 | + HIP_ERROR("Invalid iovlen: %d, scatter read is not supported yet\n", |
2150 | + msg->msg_iovlen); |
2151 | + return -ENOTSUP; |
2152 | + } |
2153 | + |
2154 | + /* Bind to an ephemeral port if the src port hasn't been bound yet */ |
2155 | + if (auto_bind(hsock)) { |
2156 | + HIP_ERROR("Fail to bind the hip socket.\n"); |
2157 | + return -1; |
2158 | + } |
2159 | + |
2160 | + /* Handle BEX if HA hasn't established */ |
2161 | + if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED |
2162 | + && hipl_hsock_ha_state(hsock) != HIP_STATE_CLOSING) { |
2163 | + return handle_bex(hsock, NULL); |
2164 | + } |
2165 | + |
2166 | + ctx.input_msg = hip_msg_alloc(); |
2167 | + ctx.output_msg = hip_msg_alloc(); |
2168 | + HIP_IFEL(!ctx.input_msg || !ctx.output_msg, -ENOMEM, |
2169 | + "hip_msg_alloc() failed\n"); |
2170 | + params.msg_name = &recv_remote_addr; |
2171 | + params.msg_namelen = sizeof(recv_remote_addr); |
2172 | + params.msg_iovlen = 1; |
2173 | + iov.iov_base = ctx.input_msg; |
2174 | + iov.iov_len = HIP_MAX_PACKET; |
2175 | + params.msg_iov = &iov; |
2176 | + |
2177 | + err = recv_msg_wrapper(hsock, ¶ms, flags, &ctx, &is_user_msg); |
2178 | + HIP_IFEL(err < 0, -1, "recv_msg_wrapper() failed\n"); |
2179 | + |
2180 | + if (validate_udp_peer_addr(hsock, &recv_remote_addr) < 0) { |
2181 | + HIP_IFEL(true, -EAGAIN, |
2182 | + "Received a packet with invalid peer address, dropping.\n"); |
2183 | + } |
2184 | + if (!is_user_msg) { |
2185 | + HIP_DEBUG("receive a hip control message.\n"); |
2186 | + hip_receive_control_packet(&ctx); |
2187 | + if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) { |
2188 | + HIP_DEBUG("HA state change to %d, return 0.\n", hsock->ha->state); |
2189 | + return 0; |
2190 | + } |
2191 | + } else { |
2192 | + HIP_DEBUG("receive a user message.\n"); |
2193 | + // TODO, if buffer size is too small, we should save it to a internal buffer |
2194 | + // and only return content with length specified by user's buffer (TCP). |
2195 | + // return error for UDP in this case. |
2196 | + struct iovec *iovp; |
2197 | + struct sockaddr_in6 *hitp; |
2198 | + hitp = msg->msg_name; |
2199 | + iovp = msg->msg_iov; |
2200 | + HIP_IFEL(iovp->iov_len < (unsigned int) err, -1, |
2201 | + "buffer size too small\n"); |
2202 | + HIP_DEBUG_HIT("ha->hit_peer:", &hsock->ha->hit_peer); |
2203 | + hitp->sin6_family = AF_INET6; |
2204 | + hitp->sin6_port = get_port_from_saddr((const struct sockaddr *) &hsock->peer_locator); |
2205 | + HIP_DEBUG("hitp port: %d\n", ntohs(hitp->sin6_port)); |
2206 | + hitp->sin6_addr = hsock->ha->hit_peer; |
2207 | + memcpy(iovp->iov_base, ctx.input_msg, err); |
2208 | + } |
2209 | + |
2210 | +out_err: |
2211 | + free(ctx.input_msg); |
2212 | + free(ctx.output_msg); |
2213 | + return err; |
2214 | +} |
2215 | + |
2216 | +/** |
2217 | + * Send data to a peer. |
2218 | + * |
2219 | + * Trigger base exchange if no host association exists. |
2220 | + * @note Data is currently sent unencrypted. |
2221 | + * @note Gather write is not supported yet. |
2222 | + * |
2223 | + * @param hsock the libhipl socket for sending data. |
2224 | + * @param msg containing data, and peer information. |
2225 | + * @param flags the flags of the socket function @c sendmsg(). |
2226 | + * @return number of bytes sent on success, |
2227 | + * -EWAITBEX if the BEX is pending, |
2228 | + * -EBEXESTABLISHED if the BEX finishes, |
2229 | + * other negative number on error. |
2230 | + */ |
2231 | +ssize_t hipl_sendmsg_internal(struct hipl_sock *const hsock, |
2232 | + struct msghdr *const msg, |
2233 | + const int flags) |
2234 | +{ |
2235 | + int fd = hsock->sock_fd; |
2236 | + |
2237 | + /* Gather write is not supported yet */ |
2238 | + if (msg->msg_iovlen > 1) { |
2239 | + HIP_ERROR("Invalid iovlen: %d, gather write is not supported\n", |
2240 | + msg->msg_iovlen); |
2241 | + return -ENOTSUP; |
2242 | + } |
2243 | + |
2244 | + /* Bind to an ephemeral port if the src port hasn't been bound yet */ |
2245 | + if (auto_bind(hsock)) { |
2246 | + HIP_ERROR("Fail to bind the hip socket.\n"); |
2247 | + return -1; |
2248 | + } |
2249 | + |
2250 | + /* Start BEX if HA hasn't established */ |
2251 | + if (hipl_hsock_ha_state(hsock) != HIP_STATE_ESTABLISHED) { |
2252 | + return handle_bex(hsock, msg->msg_name); |
2253 | + } |
2254 | + |
2255 | + /* Determine peer's locator and send out the message */ |
2256 | + HIP_DEBUG("BEX ok, start to send user data\n"); |
2257 | + if (hsock->peer_locator.ss_family == 0) { |
2258 | + hipl_build_addrstorage(&hsock->ha->peer_addr, |
2259 | + hsock->ha->peer_udp_port, |
2260 | + &hsock->peer_locator); |
2261 | + } |
2262 | + msg->msg_namelen = sizeof(hsock->peer_locator); |
2263 | + memcpy(msg->msg_name, &hsock->peer_locator, msg->msg_namelen); |
2264 | + return sendmsg(fd, msg, flags); |
2265 | +} |
2266 | |
2267 | === added file 'lib/hipl/lhipl_operations.h' |
2268 | --- lib/hipl/lhipl_operations.h 1970-01-01 00:00:00 +0000 |
2269 | +++ lib/hipl/lhipl_operations.h 2012-04-17 15:16:21 +0000 |
2270 | @@ -0,0 +1,55 @@ |
2271 | +/* |
2272 | + * Copyright (c) 2012 Aalto University and RWTH Aachen University. |
2273 | + * |
2274 | + * Permission is hereby granted, free of charge, to any person |
2275 | + * obtaining a copy of this software and associated documentation |
2276 | + * files (the "Software"), to deal in the Software without |
2277 | + * restriction, including without limitation the rights to use, |
2278 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
2279 | + * copies of the Software, and to permit persons to whom the |
2280 | + * Software is furnished to do so, subject to the following |
2281 | + * conditions: |
2282 | + * |
2283 | + * The above copyright notice and this permission notice shall be |
2284 | + * included in all copies or substantial portions of the Software. |
2285 | + * |
2286 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
2287 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
2288 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
2289 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
2290 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
2291 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
2292 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2293 | + * OTHER DEALINGS IN THE SOFTWARE. |
2294 | + */ |
2295 | + |
2296 | +#ifndef HIPL_LIB_HIPL_LHIPL_OPERATIONS_H |
2297 | +#define HIPL_LIB_HIPL_LHIPL_OPERATIONS_H |
2298 | + |
2299 | +#include "lib/hipl/lhipl_sock.h" |
2300 | + |
2301 | + |
2302 | +int hipl_socket_internal(const int family, const int type, const int protocol); |
2303 | + |
2304 | +int hipl_bind_internal(struct hipl_sock *const hsock, |
2305 | + const struct sockaddr *const address, |
2306 | + const socklen_t address_len); |
2307 | + |
2308 | +int hipl_connect_internal(struct hipl_sock *const hsock, |
2309 | + const struct sockaddr_in6 *const addr); |
2310 | + |
2311 | +int hipl_accept_internal(struct hipl_sock *const hsock); |
2312 | + |
2313 | +ssize_t hipl_recvmsg_internal(struct hipl_sock *const hsock, |
2314 | + struct msghdr *const msg, |
2315 | + const int flags); |
2316 | + |
2317 | +ssize_t hipl_sendmsg_internal(struct hipl_sock *const hsock, |
2318 | + struct msghdr *const msg, |
2319 | + const int flags); |
2320 | + |
2321 | +void hipl_build_addrstorage(const struct in6_addr *const addr, |
2322 | + const uint16_t port, |
2323 | + struct sockaddr_storage *const ss); |
2324 | + |
2325 | +#endif /* HIPL_LIB_HIPL_LHIPL_OPERATIONS_H */ |
2326 | |
2327 | === added file 'lib/hipl/lhipl_sock.c' |
2328 | --- lib/hipl/lhipl_sock.c 1970-01-01 00:00:00 +0000 |
2329 | +++ lib/hipl/lhipl_sock.c 2012-04-17 15:16:21 +0000 |
2330 | @@ -0,0 +1,150 @@ |
2331 | +/* |
2332 | + * Copyright (c) 2012 Aalto University and RWTH Aachen University. |
2333 | + * |
2334 | + * Permission is hereby granted, free of charge, to any person |
2335 | + * obtaining a copy of this software and associated documentation |
2336 | + * files (the "Software"), to deal in the Software without |
2337 | + * restriction, including without limitation the rights to use, |
2338 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
2339 | + * copies of the Software, and to permit persons to whom the |
2340 | + * Software is furnished to do so, subject to the following |
2341 | + * conditions: |
2342 | + * |
2343 | + * The above copyright notice and this permission notice shall be |
2344 | + * included in all copies or substantial portions of the Software. |
2345 | + * |
2346 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
2347 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
2348 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
2349 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
2350 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
2351 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
2352 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2353 | + * OTHER DEALINGS IN THE SOFTWARE. |
2354 | + */ |
2355 | + |
2356 | +/** |
2357 | + * @file |
2358 | + * This file contains functions for maintaining libhipl sockets. |
2359 | + */ |
2360 | + |
2361 | +#define _BSD_SOURCE |
2362 | + |
2363 | +#include <sys/socket.h> |
2364 | +#include <string.h> |
2365 | +#include <unistd.h> |
2366 | + |
2367 | +#include "lib/core/debug.h" |
2368 | +#include "lib/core/hashtable.h" |
2369 | +#include "lhipl_sock.h" |
2370 | + |
2371 | + |
2372 | +/* A hashtable to record all opening libhipl sockets */ |
2373 | +static HIP_HASHTABLE *hsocks = NULL; |
2374 | + |
2375 | +static unsigned long hipl_sk_hash(const struct hipl_sock *hsock) |
2376 | +{ |
2377 | + return hsock->sid; |
2378 | +} |
2379 | + |
2380 | +STATIC_IMPLEMENT_LHASH_HASH_FN(hipl_sk, struct hipl_sock) |
2381 | + |
2382 | +static int hipl_sk_cmp(const struct hipl_sock *hsock1, |
2383 | + const struct hipl_sock *hsock2) |
2384 | +{ |
2385 | + return memcmp(&hsock1->sid, &hsock2->sid, sizeof(hsock1->sid)); |
2386 | +} |
2387 | + |
2388 | +STATIC_IMPLEMENT_LHASH_COMP_FN(hipl_sk, struct hipl_sock) |
2389 | + |
2390 | +static uint32_t hsock_generate_id(void) |
2391 | +{ |
2392 | + static uint32_t id_generator = HIPL_LIB_HSOCK_ID_MIN; |
2393 | + |
2394 | + if (id_generator == HIPL_LIB_HSOCK_ID_MAX) { |
2395 | + id_generator = HIPL_LIB_HSOCK_ID_MIN; |
2396 | + } else { |
2397 | + id_generator += 1; |
2398 | + } |
2399 | + |
2400 | + return id_generator; |
2401 | +} |
2402 | + |
2403 | +/** |
2404 | + * Initialize the libhipl socket hashtable. |
2405 | + */ |
2406 | +void hipl_hsock_init(void) |
2407 | +{ |
2408 | + hsocks = hip_ht_init(LHASH_HASH_FN(hipl_sk), LHASH_COMP_FN(hipl_sk)); |
2409 | +} |
2410 | + |
2411 | +/** |
2412 | + * Create a new libhipl socket and save it to the libhipl socket hashtable. |
2413 | + * |
2414 | + * @param family the address family of the libhipl socket (INET or INET6). |
2415 | + * @param type the type of the protocol. |
2416 | + * @param protocol the protocol of the libhipl socket (TCP or UDP). |
2417 | + * @return pointer to the created libhipl socket on success, NULL on |
2418 | + * error. |
2419 | + */ |
2420 | +struct hipl_sock *hipl_hsock_new(const int family, const int type, |
2421 | + const int protocol) |
2422 | +{ |
2423 | + struct hipl_sock *hsock = NULL; |
2424 | + |
2425 | + hsock = calloc(sizeof(struct hipl_sock), sizeof(uint8_t)); |
2426 | + if (hsock == NULL) { |
2427 | + HIP_ERROR("calloc() failed.\n"); |
2428 | + return NULL; |
2429 | + } |
2430 | + |
2431 | + hsock->sid = hsock_generate_id(); |
2432 | + hsock->sock_family = family; |
2433 | + hsock->sock_type = type; |
2434 | + hsock->sock_proto = protocol; |
2435 | + hip_ht_add(hsocks, hsock); |
2436 | + return hsock; |
2437 | +} |
2438 | + |
2439 | +/** |
2440 | + * Get a libhipl socket by its ID. |
2441 | + * |
2442 | + * @param hsock_id the ID of the libhipl socket. |
2443 | + * @return pointer to the libhipl socket on success, or NULL if the |
2444 | + * given ID doesn't match any record. |
2445 | + */ |
2446 | +struct hipl_sock *hipl_hsock_find(const uint16_t hsock_id) |
2447 | +{ |
2448 | + struct hipl_sock hsock; |
2449 | + |
2450 | + hsock.sid = hsock_id; |
2451 | + return hip_ht_find(hsocks, &hsock); |
2452 | +} |
2453 | + |
2454 | +/** |
2455 | + * Delete a libhipl socket and free the memory it occupies. |
2456 | + * |
2457 | + * @param hsock pointer to the libhipl socket to be deleted. |
2458 | + */ |
2459 | +void hipl_hsock_delete_and_free(struct hipl_sock *const hsock) |
2460 | +{ |
2461 | + struct hipl_sock *deleted_item; |
2462 | + |
2463 | + deleted_item = hip_ht_delete(hsocks, hsock); |
2464 | + free(deleted_item); |
2465 | +} |
2466 | + |
2467 | +/** |
2468 | + * Get the HIP association state of a given libhipl socket. |
2469 | + * |
2470 | + * @param hsock the libhipl socket. |
2471 | + * @return the HIP association state of the libhipl socket. |
2472 | + */ |
2473 | +enum hip_state hipl_hsock_ha_state(const struct hipl_sock *const hsock) |
2474 | +{ |
2475 | + if (!hsock->ha) { |
2476 | + return HIP_STATE_UNASSOCIATED; |
2477 | + } else { |
2478 | + return hsock->ha->state; |
2479 | + } |
2480 | +} |
2481 | |
2482 | === added file 'lib/hipl/lhipl_sock.h' |
2483 | --- lib/hipl/lhipl_sock.h 1970-01-01 00:00:00 +0000 |
2484 | +++ lib/hipl/lhipl_sock.h 2012-04-17 15:16:21 +0000 |
2485 | @@ -0,0 +1,67 @@ |
2486 | +/* |
2487 | + * Copyright (c) 2012 Aalto University and RWTH Aachen University. |
2488 | + * |
2489 | + * Permission is hereby granted, free of charge, to any person |
2490 | + * obtaining a copy of this software and associated documentation |
2491 | + * files (the "Software"), to deal in the Software without |
2492 | + * restriction, including without limitation the rights to use, |
2493 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
2494 | + * copies of the Software, and to permit persons to whom the |
2495 | + * Software is furnished to do so, subject to the following |
2496 | + * conditions: |
2497 | + * |
2498 | + * The above copyright notice and this permission notice shall be |
2499 | + * included in all copies or substantial portions of the Software. |
2500 | + * |
2501 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
2502 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
2503 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
2504 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
2505 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
2506 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
2507 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2508 | + * OTHER DEALINGS IN THE SOFTWARE. |
2509 | + */ |
2510 | + |
2511 | +#ifndef HIPL_LIB_HIPL_LHIPL_SOCK_H |
2512 | +#define HIPL_LIB_HIPL_LHIPL_SOCK_H |
2513 | + |
2514 | +#include <limits.h> |
2515 | + |
2516 | +#include "lib/core/protodefs.h" |
2517 | +#include "lib/core/state.h" |
2518 | + |
2519 | + |
2520 | +#define HIPL_LIB_HSOCK_ID_MIN 1 |
2521 | +#define HIPL_LIB_HSOCK_ID_MAX USHRT_MAX |
2522 | +#define HIPL_LIB_HSOCK_MAX 1024 |
2523 | + |
2524 | +/* This struct contains internal information about each libhipl socket. |
2525 | + * |
2526 | + * It is generated when a new libhipl socket is created. |
2527 | + */ |
2528 | +struct hipl_sock { |
2529 | + uint16_t sid; /* libhipl socket ID */ |
2530 | + struct hip_hadb_state *ha; |
2531 | + hip_hit_t peer_hit; |
2532 | + struct sockaddr_storage peer_locator; |
2533 | + hip_hit_t src_hit; /* our HIT */ |
2534 | + int src_port; /* our port number */ |
2535 | + int sock_fd; /* underlying socket */ |
2536 | + int sock_family; |
2537 | + int sock_type; |
2538 | + int sock_proto; |
2539 | +}; |
2540 | + |
2541 | +void hipl_hsock_init(void); |
2542 | + |
2543 | +enum hip_state hipl_hsock_ha_state(const struct hipl_sock *const hsock); |
2544 | + |
2545 | +struct hipl_sock *hipl_hsock_new(const int family, const int type, |
2546 | + const int protocol); |
2547 | + |
2548 | +struct hipl_sock *hipl_hsock_find(const uint16_t hsock_id); |
2549 | + |
2550 | +void hipl_hsock_delete_and_free(struct hipl_sock *const hsock); |
2551 | + |
2552 | +#endif /* HIPL_LIB_HIPL_LHIPL_SOCK_H */ |
2553 | |
2554 | === renamed file 'hipd/lsidb.c' => 'lib/hipl/lsidb.c' |
2555 | === renamed file 'hipd/lsidb.h' => 'lib/hipl/lsidb.h' |
2556 | === renamed file 'hipd/maintenance.c' => 'lib/hipl/maintenance.c' |
2557 | === renamed file 'hipd/maintenance.h' => 'lib/hipl/maintenance.h' |
2558 | === renamed file 'hipd/nat.c' => 'lib/hipl/nat.c' |
2559 | === renamed file 'hipd/nat.h' => 'lib/hipl/nat.h' |
2560 | === renamed file 'hipd/netdev.c' => 'lib/hipl/netdev.c' |
2561 | === renamed file 'hipd/netdev.h' => 'lib/hipl/netdev.h' |
2562 | === renamed file 'hipd/nsupdate.c' => 'lib/hipl/nsupdate.c' |
2563 | === renamed file 'hipd/nsupdate.h' => 'lib/hipl/nsupdate.h' |
2564 | === renamed file 'hipd/opp_mode.c' => 'lib/hipl/opp_mode.c' |
2565 | === renamed file 'hipd/opp_mode.h' => 'lib/hipl/opp_mode.h' |
2566 | === renamed file 'hipd/output.c' => 'lib/hipl/output.c' |
2567 | --- hipd/output.c 2012-04-16 14:47:42 +0000 |
2568 | +++ lib/hipl/output.c 2012-04-17 15:16:21 +0000 |
2569 | @@ -848,7 +848,8 @@ |
2570 | HIP_ASSERT(!hit_is_opportunistic_hit(&ctx->input_msg->hit_receiver)); |
2571 | |
2572 | /* Case: I ----->IPv4---> RVS ---IPv6---> R */ |
2573 | - if (IN6_IS_ADDR_V4MAPPED(r1_src_addr) != |
2574 | + if (!hipl_is_libhip_mode() && |
2575 | + IN6_IS_ADDR_V4MAPPED(r1_src_addr) != |
2576 | IN6_IS_ADDR_V4MAPPED(r1_dst_addr)) { |
2577 | HIP_DEBUG_IN6ADDR("r1_src_addr", r1_src_addr); |
2578 | HIP_DEBUG_IN6ADDR("r1_dst_addr", r1_dst_addr); |
2579 | @@ -1217,6 +1218,9 @@ |
2580 | goto out_err; |
2581 | } |
2582 | |
2583 | + if (hipl_is_libhip_mode()) { |
2584 | + udp = 1; |
2585 | + } |
2586 | dst_is_ipv4 = IN6_IS_ADDR_V4MAPPED(peer_addr); |
2587 | len = hip_get_msg_total_len(msg); |
2588 | |
2589 | @@ -1245,13 +1249,16 @@ |
2590 | if (local_addr) { |
2591 | HIP_DEBUG("local address given\n"); |
2592 | memcpy(&my_addr, local_addr, sizeof(struct in6_addr)); |
2593 | - } else { |
2594 | + } else if (!hipl_is_libhip_mode()) { |
2595 | HIP_DEBUG("no local address, selecting one\n"); |
2596 | HIP_IFEL(hip_select_source_address(&my_addr, peer_addr), -1, |
2597 | "Cannot find source address\n"); |
2598 | + } else { |
2599 | + memset(&my_addr, 0, sizeof(my_addr)); |
2600 | } |
2601 | |
2602 | - src_is_ipv4 = IN6_IS_ADDR_V4MAPPED(&my_addr); |
2603 | + src_is_ipv4 = IN6_IS_ADDR_V4MAPPED(&my_addr) || |
2604 | + (dst_is_ipv4 && ipv6_addr_any(&my_addr)); |
2605 | |
2606 | if (src_is_ipv4) { |
2607 | IPV6_TO_IPV4_MAP(&my_addr, &src4->sin_addr); |
2608 | @@ -1305,9 +1312,10 @@ |
2609 | |
2610 | /* Handover may cause e.g. on-link duplicate address detection |
2611 | * which may cause bind to fail. */ |
2612 | - |
2613 | - HIP_IFEL(bind(hip_raw_sock_output, (struct sockaddr *) &src, sa_size), |
2614 | - -1, "Binding to raw sock failed\n"); |
2615 | + if (!hipl_is_libhip_mode()) { |
2616 | + HIP_IFEL(bind(hip_raw_sock_output, (struct sockaddr *) &src, sa_size), |
2617 | + -1, "Binding to raw sock failed\n"); |
2618 | + } |
2619 | |
2620 | #if (HIP_SIMULATE_PACKET_LOSS_PROBABILITY > 0) |
2621 | if (HIP_SIMULATE_PACKET_LOSS && HIP_SIMULATE_PACKET_IS_LOST()) { |
2622 | @@ -1324,18 +1332,25 @@ |
2623 | len = hip_get_msg_total_len(msg); |
2624 | |
2625 | if (udp) { |
2626 | - struct udphdr *uh = (struct udphdr *) msg; |
2627 | - |
2628 | - /* Insert 32 bits of zero bytes between UDP and HIP */ |
2629 | - memmove((char *) msg + HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr), msg, len); |
2630 | - memset(msg, 0, HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr)); |
2631 | - len += HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr); |
2632 | - |
2633 | - uh->source = htons(src_port); |
2634 | - uh->dest = htons(dst_port); |
2635 | - uh->len = htons(len); |
2636 | - uh->check = 0; |
2637 | - memmoved = 1; |
2638 | + if (!hipl_is_libhip_mode()) { |
2639 | + /* Insert 32 bits of zero bytes between UDP and HIP */ |
2640 | + memmove((char *) msg + HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr), msg, len); |
2641 | + memset(msg, 0, HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr)); |
2642 | + len += HIP_UDP_ZERO_BYTES_LEN + sizeof(struct udphdr); |
2643 | + |
2644 | + struct udphdr *uh = (struct udphdr *) msg; |
2645 | + uh->source = htons(src_port); |
2646 | + uh->dest = htons(dst_port); |
2647 | + uh->len = htons(len); |
2648 | + uh->check = 0; |
2649 | + } else { |
2650 | + memmove((char *) msg + HIP_UDP_ZERO_BYTES_LEN, msg, len); |
2651 | + memset(msg, 0, HIP_UDP_ZERO_BYTES_LEN); |
2652 | + len += HIP_UDP_ZERO_BYTES_LEN; |
2653 | + |
2654 | + dst4->sin_port = htons(dst_port); |
2655 | + } |
2656 | + memmoved = 1; |
2657 | } |
2658 | |
2659 | sent = sendto(hip_raw_sock_output, msg, len, 0, |
2660 | |
2661 | === renamed file 'hipd/output.h' => 'lib/hipl/output.h' |
2662 | === renamed file 'hipd/pkt_handling.c' => 'lib/hipl/pkt_handling.c' |
2663 | === renamed file 'hipd/pkt_handling.h' => 'lib/hipl/pkt_handling.h' |
2664 | === renamed file 'hipd/registration.c' => 'lib/hipl/registration.c' |
2665 | === renamed file 'hipd/registration.h' => 'lib/hipl/registration.h' |
2666 | === renamed file 'hipd/user.c' => 'lib/hipl/user.c' |
2667 | === renamed file 'hipd/user.h' => 'lib/hipl/user.h' |
2668 | === renamed file 'hipd/user_ipsec_hipd_msg.c' => 'lib/hipl/user_ipsec_hipd_msg.c' |
2669 | === renamed file 'hipd/user_ipsec_hipd_msg.h' => 'lib/hipl/user_ipsec_hipd_msg.h' |
2670 | === renamed file 'hipd/user_ipsec_sadb_api.c' => 'lib/hipl/user_ipsec_sadb_api.c' |
2671 | === renamed file 'hipd/user_ipsec_sadb_api.h' => 'lib/hipl/user_ipsec_sadb_api.h' |
2672 | === modified file 'modules/cert/hipd/cert.c' |
2673 | --- modules/cert/hipd/cert.c 2012-03-08 09:38:56 +0000 |
2674 | +++ modules/cert/hipd/cert.c 2012-04-17 15:16:21 +0000 |
2675 | @@ -33,13 +33,13 @@ |
2676 | #include <stdlib.h> |
2677 | #include <string.h> |
2678 | |
2679 | -#include "hipd/hipd.h" |
2680 | -#include "hipd/pkt_handling.h" |
2681 | #include "lib/core/builder.h" |
2682 | #include "lib/core/cert.h" |
2683 | #include "lib/core/debug.h" |
2684 | #include "lib/core/ife.h" |
2685 | #include "lib/core/protodefs.h" |
2686 | +#include "lib/hipl/hipd.h" |
2687 | +#include "lib/hipl/pkt_handling.h" |
2688 | #include "modules/midauth/hipd/midauth.h" |
2689 | #include "modules/update/hipd/update.h" |
2690 | #include "cert.h" |
2691 | |
2692 | === modified file 'modules/heartbeat/hipd/heartbeat.c' |
2693 | --- modules/heartbeat/hipd/heartbeat.c 2012-03-21 13:14:54 +0000 |
2694 | +++ modules/heartbeat/hipd/heartbeat.c 2012-04-17 15:16:21 +0000 |
2695 | @@ -65,15 +65,6 @@ |
2696 | #include <sys/types.h> |
2697 | #include <sys/socket.h> |
2698 | |
2699 | -#include "hipd/close.h" |
2700 | -#include "hipd/hadb.h" |
2701 | -#include "hipd/init.h" |
2702 | -#include "hipd/hip_socket.h" |
2703 | -#include "hipd/maintenance.h" |
2704 | -#include "hipd/nat.h" |
2705 | -#include "hipd/output.h" |
2706 | -#include "hipd/pkt_handling.h" |
2707 | -#include "hipd/user.h" |
2708 | #include "lib/core/common.h" |
2709 | #include "lib/core/debug.h" |
2710 | #include "lib/core/icomm.h" |
2711 | @@ -84,6 +75,15 @@ |
2712 | #include "lib/core/straddr.h" |
2713 | #include "lib/core/modularization.h" |
2714 | #include "lib/core/gpl/nlink.h" |
2715 | +#include "lib/hipl/close.h" |
2716 | +#include "lib/hipl/hadb.h" |
2717 | +#include "lib/hipl/hip_socket.h" |
2718 | +#include "lib/hipl/init.h" |
2719 | +#include "lib/hipl/maintenance.h" |
2720 | +#include "lib/hipl/nat.h" |
2721 | +#include "lib/hipl/output.h" |
2722 | +#include "lib/hipl/pkt_handling.h" |
2723 | +#include "lib/hipl/user.h" |
2724 | #include "heartbeat.h" |
2725 | |
2726 | #define HIP_MAX_ICMP_PACKET 512 |
2727 | |
2728 | === modified file 'modules/heartbeat_update/hipd/hb_update.c' |
2729 | --- modules/heartbeat_update/hipd/hb_update.c 2012-03-21 13:14:54 +0000 |
2730 | +++ modules/heartbeat_update/hipd/hb_update.c 2012-04-17 15:16:21 +0000 |
2731 | @@ -1,5 +1,5 @@ |
2732 | /* |
2733 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
2734 | + * Copyright (c) 2010, 2012 Aalto University and RWTH Aachen University. |
2735 | * |
2736 | * Permission is hereby granted, free of charge, to any person |
2737 | * obtaining a copy of this software and associated documentation |
2738 | @@ -40,12 +40,12 @@ |
2739 | #include <stdint.h> |
2740 | #include <stdlib.h> |
2741 | |
2742 | -#include "hipd/hadb.h" |
2743 | -#include "hipd/maintenance.h" |
2744 | #include "lib/core/builder.h" |
2745 | #include "lib/core/common.h" |
2746 | #include "lib/core/debug.h" |
2747 | #include "lib/core/protodefs.h" |
2748 | +#include "lib/hipl/hadb.h" |
2749 | +#include "lib/hipl/maintenance.h" |
2750 | #include "modules/update/hipd/update.h" |
2751 | #include "modules/update/hipd/update_locator.h" |
2752 | #include "hb_update.h" |
2753 | |
2754 | === modified file 'modules/midauth/hipd/midauth.c' |
2755 | --- modules/midauth/hipd/midauth.c 2012-04-17 11:20:20 +0000 |
2756 | +++ modules/midauth/hipd/midauth.c 2012-04-17 15:16:21 +0000 |
2757 | @@ -33,8 +33,6 @@ |
2758 | #include <stdint.h> |
2759 | #include <string.h> |
2760 | |
2761 | -#include "hipd/hidb.h" |
2762 | -#include "hipd/pkt_handling.h" |
2763 | #include "lib/core/builder.h" |
2764 | #include "lib/core/common.h" |
2765 | #include "lib/core/ife.h" |
2766 | @@ -42,6 +40,8 @@ |
2767 | #include "lib/core/protodefs.h" |
2768 | #include "lib/core/solve.h" |
2769 | #include "lib/core/state.h" |
2770 | +#include "lib/hipl/hidb.h" |
2771 | +#include "lib/hipl/pkt_handling.h" |
2772 | #include "modules/midauth/lib/midauth_builder.h" |
2773 | #include "modules/update/hipd/update.h" |
2774 | #include "midauth.h" |
2775 | |
2776 | === modified file 'modules/update/hipd/update.c' |
2777 | --- modules/update/hipd/update.c 2012-03-20 12:52:49 +0000 |
2778 | +++ modules/update/hipd/update.c 2012-04-17 15:16:21 +0000 |
2779 | @@ -37,17 +37,6 @@ |
2780 | #include <string.h> |
2781 | |
2782 | #include "config.h" |
2783 | -#include "hipd/cookie.h" |
2784 | -#include "hipd/hadb.h" |
2785 | -#include "hipd/hidb.h" |
2786 | -#include "hipd/hipd.h" |
2787 | -#include "hipd/input.h" |
2788 | -#include "hipd/maintenance.h" |
2789 | -#include "hipd/netdev.h" |
2790 | -#include "hipd/nsupdate.h" |
2791 | -#include "hipd/output.h" |
2792 | -#include "hipd/pkt_handling.h" |
2793 | -#include "hipd/user.h" |
2794 | #include "lib/core/builder.h" |
2795 | #include "lib/core/debug.h" |
2796 | #include "lib/core/hip_udp.h" |
2797 | @@ -57,6 +46,17 @@ |
2798 | #include "lib/core/prefix.h" |
2799 | #include "lib/core/state.h" |
2800 | #include "lib/core/performance.h" |
2801 | +#include "lib/hipl/cookie.h" |
2802 | +#include "lib/hipl/hadb.h" |
2803 | +#include "lib/hipl/hidb.h" |
2804 | +#include "lib/hipl/hipd.h" |
2805 | +#include "lib/hipl/input.h" |
2806 | +#include "lib/hipl/maintenance.h" |
2807 | +#include "lib/hipl/netdev.h" |
2808 | +#include "lib/hipl/nsupdate.h" |
2809 | +#include "lib/hipl/output.h" |
2810 | +#include "lib/hipl/pkt_handling.h" |
2811 | +#include "lib/hipl/user.h" |
2812 | #include "update_builder.h" |
2813 | #include "update_locator.h" |
2814 | #include "update_param_handling.h" |
2815 | |
2816 | === modified file 'modules/update/hipd/update_builder.c' |
2817 | --- modules/update/hipd/update_builder.c 2012-04-17 11:20:20 +0000 |
2818 | +++ modules/update/hipd/update_builder.c 2012-04-17 15:16:21 +0000 |
2819 | @@ -34,12 +34,12 @@ |
2820 | #include <string.h> |
2821 | #include <errno.h> |
2822 | |
2823 | -#include "hipd/hadb.h" |
2824 | -#include "hipd/netdev.h" |
2825 | #include "lib/core/builder.h" |
2826 | #include "lib/core/ife.h" |
2827 | #include "lib/core/list.h" |
2828 | #include "lib/core/prefix.h" |
2829 | +#include "lib/hipl/hadb.h" |
2830 | +#include "lib/hipl/netdev.h" |
2831 | #include "update_builder.h" |
2832 | |
2833 | enum hip_locator_traffic_type { |
2834 | |
2835 | === modified file 'modules/update/hipd/update_locator.c' |
2836 | --- modules/update/hipd/update_locator.c 2011-12-12 14:18:05 +0000 |
2837 | +++ modules/update/hipd/update_locator.c 2012-04-17 15:16:21 +0000 |
2838 | @@ -1,5 +1,5 @@ |
2839 | /* |
2840 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
2841 | + * Copyright (c) 2010, 2012 Aalto University and RWTH Aachen University. |
2842 | * |
2843 | * Permission is hereby granted, free of charge, to any person |
2844 | * obtaining a copy of this software and associated documentation |
2845 | @@ -34,11 +34,11 @@ |
2846 | #include <string.h> |
2847 | #include <openssl/lhash.h> |
2848 | |
2849 | -#include "hipd/maintenance.h" |
2850 | #include "lib/core/builder.h" |
2851 | #include "lib/core/debug.h" |
2852 | #include "lib/core/ife.h" |
2853 | #include "lib/core/protodefs.h" |
2854 | +#include "lib/hipl/maintenance.h" |
2855 | #include "update_builder.h" |
2856 | #include "update.h" |
2857 | #include "update_locator.h" |
2858 | |
2859 | === added file 'test/check_libhipl.c' |
2860 | --- test/check_libhipl.c 1970-01-01 00:00:00 +0000 |
2861 | +++ test/check_libhipl.c 2012-04-17 15:16:21 +0000 |
2862 | @@ -0,0 +1,216 @@ |
2863 | +/* |
2864 | + * Copyright (c) 2012 Aalto University and RWTH Aachen University. |
2865 | + * |
2866 | + * Permission is hereby granted, free of charge, to any person |
2867 | + * obtaining a copy of this software and associated documentation |
2868 | + * files (the "Software"), to deal in the Software without |
2869 | + * restriction, including without limitation the rights to use, |
2870 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
2871 | + * copies of the Software, and to permit persons to whom the |
2872 | + * Software is furnished to do so, subject to the following |
2873 | + * conditions: |
2874 | + * |
2875 | + * The above copyright notice and this permission notice shall be |
2876 | + * included in all copies or substantial portions of the Software. |
2877 | + * |
2878 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
2879 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
2880 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
2881 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
2882 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
2883 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
2884 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2885 | + * OTHER DEALINGS IN THE SOFTWARE. |
2886 | + */ |
2887 | + |
2888 | +/** |
2889 | + * @file |
2890 | + * @brief Tests of libhipl on localhost (see doc/HACKING on unit tests). |
2891 | + */ |
2892 | + |
2893 | +#include <arpa/inet.h> |
2894 | +#include <check.h> |
2895 | +#include <errno.h> |
2896 | +#include <stdbool.h> |
2897 | +#include <stdio.h> |
2898 | +#include <stdlib.h> |
2899 | +#include <sys/select.h> |
2900 | +#include <unistd.h> |
2901 | + |
2902 | +#include "lib/hipl/hidb.h" |
2903 | +#include "lib/hipl/lhipl.h" |
2904 | + |
2905 | +#ifndef max |
2906 | +#define max(a, b) (((a) > (b)) ? (a) : (b)) |
2907 | +#endif |
2908 | + |
2909 | +#define LO_IP "127.0.0.1" |
2910 | +#define TEST_MSG "Hello Sailor!" |
2911 | +#define SEND_PORT 22345 |
2912 | +#define RECV_PORT 22300 |
2913 | + |
2914 | +static struct in6_addr lo_hit; |
2915 | +static char peername[HIPL_MAX_PEERNAME]; |
2916 | +static struct sockaddr_in send_addr; |
2917 | +static struct sockaddr_in recv_addr; |
2918 | + |
2919 | +static int sender; |
2920 | +static int receiver; |
2921 | + |
2922 | +static void test_libhipl_lo_init(int proto) |
2923 | +{ |
2924 | + if (hipl_lib_init_all(HIPL_LIB_LOG_NONE) < 0) { |
2925 | + fail("hipl_lib_init_all"); |
2926 | + } |
2927 | + |
2928 | + fail_if(hip_get_default_hit(&lo_hit) < 0, "Failed to load local hit"); |
2929 | + inet_ntop(AF_INET6, &lo_hit, peername, HIPL_MAX_PEERNAME); |
2930 | + fail_if(hipl_add_peer_info(peername, LO_IP) < 0, |
2931 | + "Failed to insert peer info"); |
2932 | + |
2933 | + send_addr.sin_family = AF_INET; |
2934 | + inet_pton(AF_INET, LO_IP, &send_addr.sin_addr); |
2935 | + send_addr.sin_port = htons(SEND_PORT); |
2936 | + recv_addr.sin_family = AF_INET; |
2937 | + inet_pton(AF_INET, LO_IP, &recv_addr.sin_addr); |
2938 | + recv_addr.sin_port = htons(RECV_PORT); |
2939 | + |
2940 | + if (proto == IPPROTO_TCP) { |
2941 | + sender = hipl_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
2942 | + receiver = hipl_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
2943 | + } else if (proto == IPPROTO_UDP) { |
2944 | + sender = hipl_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
2945 | + receiver = hipl_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
2946 | + } |
2947 | + fail_if(sender <= 0 || receiver <= 0); |
2948 | + |
2949 | + if (hipl_bind(sender, (struct sockaddr *) &send_addr, |
2950 | + sizeof(send_addr)) < 0) { |
2951 | + fail("hipl_bind() for sender"); |
2952 | + } |
2953 | + if (hipl_bind(receiver, (struct sockaddr *) &recv_addr, |
2954 | + sizeof(recv_addr)) < 0) { |
2955 | + fail("hipl_bind() for receiver"); |
2956 | + } |
2957 | + |
2958 | + hipl_lib_set_bex_feedback(true); |
2959 | +} |
2960 | + |
2961 | +static void test_libhipl_lo_main_loop(int send_hid, int recv_hid) |
2962 | +{ |
2963 | + char peer[HIPL_MAX_PEERNAME]; |
2964 | + uint16_t peer_port; |
2965 | + char buf[1024]; |
2966 | + fd_set rset; |
2967 | + int ret = 0; |
2968 | + int maxfd = max(hipl_lib_get_sockfd(send_hid), |
2969 | + hipl_lib_get_sockfd(recv_hid)); |
2970 | + |
2971 | + //trigger BEX |
2972 | + ret = hipl_sendto(send_hid, TEST_MSG, strlen(TEST_MSG), 0, |
2973 | + peername, RECV_PORT); |
2974 | + fail_if(ret != -EWAITBEX); |
2975 | + |
2976 | + while (1) { |
2977 | + FD_ZERO(&rset); |
2978 | + FD_SET(hipl_lib_get_sockfd(send_hid), &rset); |
2979 | + FD_SET(hipl_lib_get_sockfd(recv_hid), &rset); |
2980 | + fail_if(select(maxfd + 1, &rset, NULL, NULL, NULL) < 0); |
2981 | + |
2982 | + if (FD_ISSET(hipl_lib_get_sockfd(recv_hid), &rset)) { |
2983 | + ret = hipl_recvfrom(recv_hid, buf, 1024, 0, peer, &peer_port); |
2984 | + fail_if(ret < 0 && ret != -EWAITBEX && ret != -EBEXESTABLISHED); |
2985 | + fail_if(ret > 0 && ret != strlen(TEST_MSG)); |
2986 | + |
2987 | + if (ret == strlen(TEST_MSG)) { |
2988 | + buf[ret] = '\0'; |
2989 | + fail_if(strcmp(buf, TEST_MSG) != 0); |
2990 | + fail_if(strcmp(peername, peer) != 0); |
2991 | + fail_if(peer_port != SEND_PORT); |
2992 | + return; |
2993 | + } |
2994 | + } |
2995 | + if (FD_ISSET(hipl_lib_get_sockfd(send_hid), &rset)) { |
2996 | + ret = hipl_sendto(send_hid, TEST_MSG, strlen(TEST_MSG), 0, |
2997 | + peername, RECV_PORT); |
2998 | + fail_if(ret < 0 && ret != -EWAITBEX && ret != -EBEXESTABLISHED); |
2999 | + fail_if(ret > 0 && ret != strlen(TEST_MSG)); |
3000 | + } |
3001 | + } |
3002 | +} |
3003 | + |
3004 | +START_TEST(test_libhipl_lo_tcp) |
3005 | +{ |
3006 | + fd_set wset, rset; |
3007 | + int maxfd, recv_slave = 0; |
3008 | + |
3009 | + test_libhipl_lo_init(IPPROTO_TCP); |
3010 | + |
3011 | + // Setup TCP connection |
3012 | + maxfd = max(hipl_lib_get_sockfd(sender), hipl_lib_get_sockfd(receiver)); |
3013 | + if (hipl_listen(receiver, 5) < 0) { |
3014 | + fail("hipl_listen()"); |
3015 | + } |
3016 | + fail_if(hipl_lib_set_nonblock(sender, true) < 0); |
3017 | + fail_if(hipl_lib_set_nonblock(receiver, true) < 0); |
3018 | + hipl_accept(receiver); |
3019 | + hipl_connect(sender, peername, RECV_PORT); |
3020 | + while (recv_slave <= 0) { |
3021 | + FD_ZERO(&wset); |
3022 | + FD_ZERO(&rset); |
3023 | + FD_SET(hipl_lib_get_sockfd(sender), &wset); |
3024 | + FD_SET(hipl_lib_get_sockfd(receiver), &rset); |
3025 | + fail_if(select(maxfd + 1, &rset, &wset, NULL, NULL) < 0); |
3026 | + if (FD_ISSET(hipl_lib_get_sockfd(receiver), &rset)) { |
3027 | + if ((recv_slave = hipl_accept(receiver)) < 0) { |
3028 | + fail("hipl_accept(), %s", strerror(errno)); |
3029 | + } |
3030 | + } |
3031 | + if (FD_ISSET(hipl_lib_get_sockfd(sender), &wset)) { |
3032 | + if (hipl_connect(sender, peername, RECV_PORT) < 0 |
3033 | + && errno != EINPROGRESS && errno != EISCONN) { |
3034 | + fail("hipl_connect() %s", strerror(errno)); |
3035 | + } |
3036 | + } |
3037 | + } |
3038 | + fail_if(hipl_connect(sender, peername, RECV_PORT) < 0 && errno != EISCONN); |
3039 | + fail_if(hipl_lib_set_nonblock(sender, false) < 0); |
3040 | + |
3041 | + // Process base exchange and user data |
3042 | + test_libhipl_lo_main_loop(sender, recv_slave); |
3043 | +} |
3044 | +END_TEST |
3045 | + |
3046 | +START_TEST(test_libhipl_lo_udp) |
3047 | +{ |
3048 | + test_libhipl_lo_init(IPPROTO_UDP); |
3049 | + test_libhipl_lo_main_loop(sender, receiver); |
3050 | +} |
3051 | +END_TEST |
3052 | + |
3053 | +static Suite *hipnc_suite(void) |
3054 | +{ |
3055 | + Suite *s = suite_create("libhipl"); |
3056 | + |
3057 | + TCase *tc_libhipl_lo = tcase_create("libhipl_lo"); |
3058 | + tcase_add_test(tc_libhipl_lo, test_libhipl_lo_udp); |
3059 | + tcase_add_test(tc_libhipl_lo, test_libhipl_lo_tcp); |
3060 | + suite_add_tcase(s, tc_libhipl_lo); |
3061 | + |
3062 | + return s; |
3063 | +} |
3064 | + |
3065 | +int main(void) |
3066 | +{ |
3067 | + int number_failed; |
3068 | + Suite *s = hipnc_suite(); |
3069 | + SRunner *sr = srunner_create(NULL); |
3070 | + |
3071 | + srunner_add_suite(sr, s); |
3072 | + srunner_run_all(sr, CK_NORMAL); |
3073 | + |
3074 | + number_failed = srunner_ntests_failed(sr); |
3075 | + srunner_free(sr); |
3076 | + |
3077 | + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; |
3078 | +} |
3079 | |
3080 | === modified file 'test/hipd/lsidb.c' |
3081 | --- test/hipd/lsidb.c 2012-01-18 21:09:47 +0000 |
3082 | +++ test/hipd/lsidb.c 2012-04-17 15:16:21 +0000 |
3083 | @@ -26,7 +26,7 @@ |
3084 | #include <check.h> |
3085 | #include <stdlib.h> |
3086 | |
3087 | -#include "hipd/lsidb.c" |
3088 | +#include "lib/hipl/lsidb.c" |
3089 | #include "test_suites.h" |
3090 | |
3091 | START_TEST(test_lsidb_allocate_lsi_valid) |
> === modified file 'lib/core/hostid.c' dup[strlen( hi_file) + 1]; create_ dir(dirname( hi_file_ dup), HIP_DIR_MODE))) {
> --- 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_
> + strcpy(hi_file_dup, hi_file);
> + if ((err = check_and_
> + 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' linkedlist. c 2011-08-15 14:11:56 +0000 linkedlist. c 2012-02-20 08:33:22 +0000 del_by_ ptr(struct hip_ll *linkedlist, void *ptr, >element_ count > 0 >head-> ptr == ptr) { >element_ count-- ; tmp->ptr) ; >element_ count-- ; curr->ptr) ;
> --- lib/core/
> +++ lib/core/
> @@ -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_
> + free_elem_fn free_element)
> +{
> + struct hip_ll_node *curr;
> + struct hip_ll_node *tmp;
> +
> + /* match first list node */
> + if (linkedlist != NULL && linkedlist-
> + && linkedlist-
> + tmp = linkedlist->head;
> + linkedlist->head = tmp->next;
> + linkedlist-
> + if (free_element != NULL) {
> + free_element(
> + }
> + 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-
> + if (free_element != NULL) {
> + free_element(
> + }
> + 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... .