Re: iked(8): add support for IKEv2 Message Fragmentation
> I'm wondering if we should make this the default. I'm seeing no breakage > as a result of using it, and it fixes things with some annoying network > configurations. The option does add overhead though because it will fragment messages even if the MTU is big enough. As a result it will add some latecy to the key exchange. On the other hand, usually only messages containing certificates are big enough to trigger fragmentation, so the impact is probably quite low. >From a compatibility point of view, fragmentation should only fix things and not break anything. I'm ok with this as the default config should be one that "just works" for all network configurations. Those that want better latency can still turn it off.
Re: iked(8): add support for IKEv2 Message Fragmentation
I'm wondering if we should make this the default. I'm seeing no breakage as a result of using it, and it fixes things with some annoying network configurations. Index: iked.conf.5 === RCS file: /cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.55 diff -u -p -r1.55 iked.conf.5 --- iked.conf.5 11 May 2019 16:30:23 - 1.55 +++ iked.conf.5 24 Aug 2019 09:28:01 - @@ -139,9 +139,9 @@ This mode is only useful for testing and .It Ic set fragmentation Enable IKEv2 Message Fragmentation (RFC 7383) support. This allows IKEv2 to operate in environments that might block IP fragments. +This is the default. .It Ic set nofragmentation Disables IKEv2 Message Fragmentation support. -This is the default. .It Ic set mobike Enable MOBIKE (RFC 4555) support. This is the default. Index: parse.y === RCS file: /cvs/src/sbin/iked/parse.y,v retrieving revision 1.81 diff -u -p -r1.81 parse.y --- parse.y 28 Jun 2019 13:32:44 - 1.81 +++ parse.y 24 Aug 2019 09:28:01 - @@ -106,7 +106,7 @@ static int rules = 0; static int passive = 0; static int decouple = 0; static int mobike = 1; -static int fragmentation = 0; +static int fragmentation = 1; static char*ocsp_url = NULL; struct ipsec_xf { @@ -1586,7 +1586,7 @@ parse_config(const char *filename, struc free(ocsp_url); mobike = 1; - fragmentation = 0; + fragmentation = 1; decouple = passive = 0; ocsp_url = NULL;
Re: iked(8): add support for IKEv2 Message Fragmentation
Hey, I updated the diff to work with the recent fixes. Currently next_pl is checked to be the encrypted payload after the IKE_SA_INIT exchange, this also whitelists the new encrypted fragment payload. Also ikev2_send_encrypted_fragments() now uses the new sa_msgid_current instead of sa_msgid just like ikev2_msg_send_encrypt() does. Ok? Index: sbin/iked/config.c === RCS file: /mount/openbsd/cvs/src/sbin/iked/config.c,v retrieving revision 1.49 diff -u -p -u -r1.49 config.c --- sbin/iked/config.c 27 Nov 2017 18:39:35 - 1.49 +++ sbin/iked/config.c 11 May 2019 15:39:40 - @@ -1,6 +1,7 @@ /* $OpenBSD: config.c,v 1.49 2017/11/27 18:39:35 patrick Exp $ */ /* + * Copyright (c) 2019 Tobias Heider * Copyright (c) 2010-2013 Reyk Floeter * * Permission to use, copy, modify, and distribute this software for any @@ -94,12 +95,29 @@ config_free_kex(struct iked_kex *kex) } void +config_free_fragments(struct iked_frag *frag) +{ + size_t i; + + if (frag && frag->frag_arr) { + for (i = 0; i < frag->frag_total; i++) { + if (frag->frag_arr[i] != NULL) + free(frag->frag_arr[i]->frag_data); + free(frag->frag_arr[i]); + } + free(frag->frag_arr); + bzero(frag, sizeof(struct iked_frag)); + } +} + +void config_free_sa(struct iked *env, struct iked_sa *sa) { timer_del(env, >sa_timer); timer_del(env, >sa_keepalive); timer_del(env, >sa_rekey); + config_free_fragments(>sa_fragments); config_free_proposals(>sa_proposals, 0); config_free_childsas(env, >sa_childsas, NULL, NULL); sa_free_flows(env, >sa_flows); @@ -834,6 +852,29 @@ config_getmobike(struct iked *env, struc memcpy(, imsg->data, sizeof(boolval)); env->sc_mobike = boolval; log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no "); + return (0); +} + +int +config_setfragmentation(struct iked *env) +{ + unsigned int boolval; + + boolval = env->sc_frag; + proc_compose(>sc_ps, PROC_IKEV2, IMSG_CTL_FRAGMENTATION, + , sizeof(boolval)); + return (0); +} + +int +config_getfragmentation(struct iked *env, struct imsg *imsg) +{ + unsigned int boolval; + + IMSG_SIZE_CHECK(imsg, ); + memcpy(, imsg->data, sizeof(boolval)); + env->sc_frag = boolval; + log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); return (0); } Index: sbin/iked/iked.c === RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.c,v retrieving revision 1.36 diff -u -p -u -r1.36 iked.c --- sbin/iked/iked.c27 Nov 2017 18:39:35 - 1.36 +++ sbin/iked/iked.c11 May 2019 15:39:40 - @@ -1,6 +1,7 @@ /* $OpenBSD: iked.c,v 1.36 2017/11/27 18:39:35 patrick Exp $ */ /* + * Copyright (c) 2019 Tobias Heider * Copyright (c) 2010-2013 Reyk Floeter * * Permission to use, copy, modify, and distribute this software for any @@ -251,6 +252,7 @@ parent_configure(struct iked *env) fatal("pledge"); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); @@ -282,6 +284,7 @@ parent_reload(struct iked *env, int rese config_setcompile(env, PROC_IKEV2); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); Index: sbin/iked/iked.conf.5 === RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.54 diff -u -p -u -r1.54 iked.conf.5 --- sbin/iked/iked.conf.5 2 Apr 2019 09:42:55 - 1.54 +++ sbin/iked/iked.conf.5 11 May 2019 15:39:40 - @@ -136,6 +136,12 @@ This is the default. .It Ic set decouple Don't load the negotiated SAs and flows from the kernel. This mode is only useful for testing and debugging. +.It Ic set fragmentation +Enable IKEv2 Message Fragmentation (RFC 7383) support. +This allows IKEv2 to operate in environments that might block IP fragments. +.It Ic set nofragmentation +Disables IKEv2 Message Fragmentation support. +This is the default. .It Ic set mobike Enable MOBIKE (RFC 4555) support. This is the default. Index: sbin/iked/iked.h === RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.h,v retrieving revision 1.120 diff -u -p -u -r1.120 iked.h --- sbin/iked/iked.h10 May 2019 15:02:17 - 1.120 +++ sbin/iked/iked.h11 May 2019 15:39:40 -
Re: iked(8): add support for IKEv2 Message Fragmentation
Tim Stewart writes: > On 3/30/19 3:11 PM, Tobias Heider wrote: >> Hi Stuart, >> >> I'm glad to see people are using this. >> There's some smaller fixes that I haven't sent to the list yet, so >> probably I'll send an updated diff on monday. > > I plan to start using this patch this week, likely as soon as you send > the updated diff. I started on the same feature in June of 2018, but > other tasks took priority and it stalled. > > I have a pretty good testbed for this, as I have several site-to-site > links that drop UDP fragments and several road warriors that would > experience fragment drops depending on the cell network they use. I > will report back on this thread with my findings. > > Thanks for the patch! > > -TimS I have been using this patch for over a week and it has increased the reliability of my road warrior VPN as I move across a variety of networks. It also allows one of my previously-broken site-to-site VPNs to function again. Thanks! I did have one strange problem today, and I have no idea if it's related to this patch or not. One of my site-to-site connections went down and I saw the following in one of the peer's log: Apr 16 12:59:05 site-a iked[15114]: ikev2_msg_send: sendtofrom: No buffer space available Apr 16 13:00:07 site-a iked[15114]: ikev2_msg_send: INFORMATIONAL request from 5.6.7.8:500 to 1.2.3.4:500 msgid 929, 80 bytes Apr 16 13:00:07 site-a iked[15114]: ikev2_recv: INFORMATIONAL response from responder 1.2.3.4:500 to 5.6.7.8:500 policy 'central' id 929, 80 bytes Apr 16 13:01:07 site-a iked[15114]: ikev2_msg_send: INFORMATIONAL request from 5.6.7.8:500 to 1.2.3.4:500 msgid 930, 80 bytes Apr 16 13:01:07 site-a iked[15114]: ikev2_recv: INFORMATIONAL response from responder 1.2.3.4:500 to 5.6.7.8:500 policy 'central' id 930, 80 bytes Apr 16 13:02:07 site-a iked[15114]: ikev2_msg_send: INFORMATIONAL request from 5.6.7.8:500 to 1.2.3.4:500 msgid 931, 80 bytes Apr 16 13:02:07 site-a iked[15114]: ikev2_recv: INFORMATIONAL response from responder 1.2.3.4:500 to 5.6.7.8:500 policy 'central' id 931, 80 bytes Apr 16 13:03:00 site-a iked[15114]: ikev2_acquire_sa: flow wasn't found Apr 16 13:03:07 site-a iked[15114]: pfkey_sa_last_used: message: No such process Apr 16 13:03:07 site-a iked[15114]: pfkey_sa_last_used: message: No such process Apr 16 13:03:30 site-a iked[15114]: ikev2_acquire_sa: flow wasn't found Apr 16 13:04:00 site-a iked[15114]: ikev2_acquire_sa: flow wasn't found Apr 16 13:04:02 site-a iked[15114]: ikev2_recv: INFORMATIONAL request from responder 1.2.3.4:500 to 5.6.7.8:500 policy 'central' id 0, 80 bytes Apr 16 13:04:02 site-a iked[15114]: ikev2_msg_send: INFORMATIONAL response from 5.6.7.8:500 to 1.2.3.4:500 msgid 0, 80 bytes Apr 16 13:04:07 site-a iked[15114]: pfkey_sa_last_used: message: No such process Apr 16 13:04:07 site-a iked[15114]: pfkey_sa_last_used: message: No such process Apr 16 13:04:30 site-a iked[15114]: ikev2_acquire_sa: flow wasn't found Apr 16 13:05:00 site-a iked[15114]: ikev2_acquire_sa: flow wasn't found Apr 16 13:05:04 site-a iked[15114]: ikev2_recv: INFORMATIONAL request from responder 1.2.3.4:500 to 5.6.7.8:500 policy 'central' id 1, 80 bytes Apr 16 13:05:04 site-a iked[15114]: ikev2_msg_send: INFORMATIONAL response from 5.6.7.8:500 to 1.2.3.4:500 msgid 1, 80 bytes I restarted site-a's iked and everything came back up and has been working fine since. I see there are some other iked patches in-flight on this list (including a new version of this one), so I'm happy to punt on this for now and see if it happens again after I've applied the latest versions of all patches. -TimS >> On 3/30/19 6:43 PM, Stuart Henderson wrote: >>> This diff hasn't gone anywhere recently - I've been using it since >>> Tobias posted it with no problems. Any comments on whether it should >>> go in, and if so, before/after 6.5? The feature is disabled by default. >>> >>> Index: config.c >>> === >>> RCS file: /cvs/src/sbin/iked/config.c,v >>> retrieving revision 1.49 >>> diff -u -p -r1.49 config.c >>> --- config.c27 Nov 2017 18:39:35 - 1.49 >>> +++ config.c30 Mar 2019 17:41:33 - >>> @@ -94,12 +94,30 @@ config_free_kex(struct iked_kex *kex) >>> } >>> void >>> +config_free_fragments(struct iked_frag *frag) >>> +{ >>> + size_t i; >>> + if (frag && frag->frag_arr) { >>> + for (i = 0; i < frag->frag_count; i++) { >>> + free(frag->frag_arr[i]->frag_data); >>> + frag->frag_arr[i]->frag_data = NULL; >>> + free(frag->frag_arr[i]); >>> + frag->frag_arr[i] = NULL; >>> + } >>> + free(frag->frag_arr); >>> + frag->frag_arr = NULL; >>> + bzero(frag, sizeof(struct iked_frag)); >>> + } >>> +} >>> + >>> +void >>> config_free_sa(struct iked *env, struct iked_sa *sa) >>> { >>> timer_del(env, >sa_timer); >>> timer_del(env,
Re: iked(8): add support for IKEv2 Message Fragmentation
Another update which fixes a problem with loosing the sa_frag state when rekeying the IKE SA, fixes some formatting and adresses some complaints about the msg_retransmit and msg_dispose API. Index: sbin/iked//config.c === RCS file: /mount/openbsd/cvs/src/sbin/iked/config.c,v retrieving revision 1.49 diff -u -p -u -r1.49 config.c --- sbin/iked//config.c 27 Nov 2017 18:39:35 - 1.49 +++ sbin/iked//config.c 8 Apr 2019 16:00:24 - @@ -1,6 +1,7 @@ /* $OpenBSD: config.c,v 1.49 2017/11/27 18:39:35 patrick Exp $ */ /* + * Copyright (c) 2019 Tobias Heider * Copyright (c) 2010-2013 Reyk Floeter * * Permission to use, copy, modify, and distribute this software for any @@ -94,12 +95,29 @@ config_free_kex(struct iked_kex *kex) } void +config_free_fragments(struct iked_frag *frag) +{ + size_t i; + + if (frag && frag->frag_arr) { + for (i = 0; i < frag->frag_total; i++) { + if (frag->frag_arr[i] != NULL) + free(frag->frag_arr[i]->frag_data); + free(frag->frag_arr[i]); + } + free(frag->frag_arr); + bzero(frag, sizeof(struct iked_frag)); + } +} + +void config_free_sa(struct iked *env, struct iked_sa *sa) { timer_del(env, >sa_timer); timer_del(env, >sa_keepalive); timer_del(env, >sa_rekey); + config_free_fragments(>sa_fragments); config_free_proposals(>sa_proposals, 0); config_free_childsas(env, >sa_childsas, NULL, NULL); sa_free_flows(env, >sa_flows); @@ -836,6 +854,30 @@ config_getmobike(struct iked *env, struc log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no "); return (0); } + +int +config_setfragmentation(struct iked *env) +{ + unsigned int boolval; + + boolval = env->sc_frag; + proc_compose(>sc_ps, PROC_IKEV2, IMSG_CTL_FRAGMENTATION, + , sizeof(boolval)); + return (0); +} + +int +config_getfragmentation(struct iked *env, struct imsg *imsg) +{ + unsigned int boolval; + + IMSG_SIZE_CHECK(imsg, ); + memcpy(, imsg->data, sizeof(boolval)); + env->sc_frag = boolval; + log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); + return (0); +} + int config_setocsp(struct iked *env) Index: sbin/iked//iked.c === RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.c,v retrieving revision 1.36 diff -u -p -u -r1.36 iked.c --- sbin/iked//iked.c 27 Nov 2017 18:39:35 - 1.36 +++ sbin/iked//iked.c 8 Apr 2019 16:00:24 - @@ -1,6 +1,7 @@ /* $OpenBSD: iked.c,v 1.36 2017/11/27 18:39:35 patrick Exp $ */ /* + * Copyright (c) 2019 Tobias Heider * Copyright (c) 2010-2013 Reyk Floeter * * Permission to use, copy, modify, and distribute this software for any @@ -251,6 +252,7 @@ parent_configure(struct iked *env) fatal("pledge"); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); @@ -282,6 +284,7 @@ parent_reload(struct iked *env, int rese config_setcompile(env, PROC_IKEV2); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); Index: sbin/iked//iked.conf.5 === RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.54 diff -u -p -u -r1.54 iked.conf.5 --- sbin/iked//iked.conf.5 2 Apr 2019 09:42:55 - 1.54 +++ sbin/iked//iked.conf.5 8 Apr 2019 16:00:24 - @@ -136,6 +136,12 @@ This is the default. .It Ic set decouple Don't load the negotiated SAs and flows from the kernel. This mode is only useful for testing and debugging. +.It Ic set fragmentation +Enable IKEv2 Message Fragmentation (RFC 7383) support. +This allows IKEv2 to operate in environments that might block IP fragments. +.It Ic set nofragmentation +Disables IKEv2 Message Fragmentation support. +This is the default. .It Ic set mobike Enable MOBIKE (RFC 4555) support. This is the default. Index: sbin/iked//iked.h === RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.h,v retrieving revision 1.119 diff -u -p -u -r1.119 iked.h --- sbin/iked//iked.h 6 Aug 2018 06:30:06 - 1.119 +++ sbin/iked//iked.h 8 Apr 2019 16:00:24 - @@ -1,6 +1,7 @@ /* $OpenBSD: iked.h,v 1.119 2018/08/06 06:30:06 mestre Exp $ */ /* + * Copyright (c) 2019 Tobias Heider * Copyright (c) 2010-2013 Reyk Floeter * *
Re: iked(8): add support for IKEv2 Message Fragmentation
Here's the update. What changed: - fixed cleanup of fragments in SA - fixed retransmission of fragmented messages - adjusted copyright headers - Added some comments I also included Stuart's manpage parts as well as some line breaks. We've been testing this version and haven't found anything off so far, looking forward to your results. Regards, Tobias Index: regress/sbin/iked/parser/common.c === RCS file: /mount/openbsd/cvs/src/regress/sbin/iked/parser/common.c,v retrieving revision 1.1 diff -u -p -u -r1.1 common.c --- regress/sbin/iked/parser/common.c 29 May 2017 20:59:28 - 1.1 +++ regress/sbin/iked/parser/common.c 1 Apr 2019 12:46:40 - @@ -166,6 +166,11 @@ config_add_proposal(struct iked_proposal return (NULL); } +void config_free_fragments(struct iked_frag *frag) +{ + return; +} + int ikev2_send_informational(struct iked *env, struct iked_message *msg) { Index: regress/sbin/iked/parser/test_parser_fuzz.c === RCS file: /mount/openbsd/cvs/src/regress/sbin/iked/parser/test_parser_fuzz.c,v retrieving revision 1.2 diff -u -p -u -r1.2 test_parser_fuzz.c --- regress/sbin/iked/parser/test_parser_fuzz.c 22 Mar 2018 21:11:49 - 1.2 +++ regress/sbin/iked/parser/test_parser_fuzz.c 1 Apr 2019 12:46:40 - @@ -183,6 +183,50 @@ u_int8_t ts_pld[] = { 0xac, 0x28, 0x7d, 0x00, 0xac, 0x28, 0x7d, 0xff }; +uint8_t skf_1of1_pld[] = { + 0x21, 0x00, 0x01, 0x98, 0x00, 0x01, 0x00, 0x01, 0x14, 0x77, + 0x25, 0x7b, 0x82, 0xc0, 0xdb, 0x0b, 0x24, 0x36, 0x36, 0x13, + 0x36, 0xe4, 0x99, 0xad, 0xf5, 0xaf, 0x26, 0x6f, 0x47, 0xd2, + 0x0d, 0x65, 0xe1, 0xa8, 0xcb, 0x35, 0x1e, 0x53, 0xce, 0x6d, + 0x8e, 0xf9, 0xe4, 0x51, 0xe3, 0x27, 0x10, 0x43, 0x38, 0x84, + 0x54, 0x1d, 0x7a, 0x1a, 0x89, 0x34, 0x06, 0xb3, 0x62, 0x86, + 0x98, 0x3b, 0x39, 0x91, 0x6e, 0xe8, 0x65, 0x3e, 0x31, 0xa8, + 0x08, 0xfe, 0x83, 0x56, 0x30, 0xd3, 0xe0, 0xfd, 0x73, 0x92, + 0x85, 0x2d, 0xae, 0x1d, 0x7d, 0xdb, 0x47, 0x05, 0x57, 0xe7, + 0x8e, 0xc5, 0xa5, 0x1b, 0x0e, 0x85, 0x1f, 0x12, 0x6d, 0xe6, + 0xdb, 0x3a, 0x3e, 0x99, 0xd1, 0x23, 0x41, 0xa4, 0x1c, 0x46, + 0x38, 0xd1, 0xa8, 0x84, 0x96, 0x13, 0xdb, 0x2a, 0x1d, 0x3b, + 0xb8, 0xd2, 0x04, 0xb3, 0x0d, 0xb4, 0x71, 0x90, 0xdb, 0xf6, + 0x2d, 0x60, 0x01, 0xc2, 0xb2, 0x89, 0xbd, 0xe9, 0x95, 0x7b, + 0x53, 0xa4, 0x94, 0x7e, 0x12, 0xe9, 0x5f, 0xfc, 0x51, 0x17, + 0x94, 0x3e, 0xba, 0xc2, 0xa5, 0x4d, 0x3a, 0x4d, 0x4b, 0x95, + 0x6d, 0x91, 0xc2, 0xb0, 0x2d, 0xb7, 0x24, 0xe8, 0x3b, 0xbd, + 0xe0, 0xcc, 0x09, 0x50, 0x11, 0x83, 0xc0, 0xcd, 0x29, 0x33, + 0xd5, 0x8f, 0x8a, 0xd1, 0xe3, 0xe8, 0x4f, 0x6a, 0x10, 0x4a, + 0x64, 0x97, 0x0f, 0x38, 0x58, 0x8d, 0x7f, 0x5d, 0xb4, 0x6b, + 0xa0, 0x42, 0x5e, 0x95, 0xe6, 0x08, 0x3e, 0x01, 0xf8, 0x82, + 0x90, 0x81, 0xd4, 0x70, 0xb5, 0xb2, 0x8c, 0x64, 0xa9, 0x56, + 0xdd, 0xc2, 0xda, 0xe1, 0xd3, 0xad, 0xf8, 0x5b, 0x99, 0x0b, + 0x19, 0x5e, 0x88, 0x0d, 0x81, 0x04, 0x4d, 0xc1, 0x43, 0x41, + 0xf1, 0xd3, 0x45, 0x65, 0x62, 0x70, 0x2f, 0xfa, 0x62, 0xbe, + 0x7d, 0xf4, 0x94, 0x91, 0xe0, 0xbb, 0xb1, 0xbc, 0xe5, 0x27, + 0xc8, 0x15, 0xd4, 0xcb, 0x82, 0x97, 0x15, 0x46, 0x82, 0xbb, + 0x48, 0xbb, 0x16, 0x25, 0xbe, 0x82, 0xe4, 0x27, 0x80, 0xf3, + 0xc2, 0x92, 0x3b, 0xd6, 0xc3, 0x65, 0x20, 0xec, 0x50, 0xdb, + 0x6a, 0xcb, 0x47, 0x73, 0xf7, 0x98, 0xf1, 0x66, 0x5e, 0xc4, + 0xe9, 0x87, 0xf8, 0xcb, 0x1e, 0x06, 0xa7, 0x67, 0xf5, 0xec, + 0x73, 0xe5, 0xc7, 0x4d, 0xc2, 0x90, 0xe4, 0xdf, 0x9d, 0x1f, + 0x05, 0x67, 0x99, 0xd6, 0xf0, 0xc4, 0x20, 0xbc, 0xf8, 0xf5, + 0x3e, 0x19, 0xe9, 0x3a, 0x12, 0xe1, 0xcc, 0x9f, 0x81, 0x55, + 0x1e, 0xad, 0xc8, 0xa3, 0xe5, 0x98, 0xbe, 0xe0, 0x4d, 0xb7, + 0x6b, 0xd5, 0xbe, 0x6a, 0x3d, 0x76, 0xb6, 0xe2, 0xa5, 0xa7, + 0x96, 0x68, 0xeb, 0x91, 0xee, 0x02, 0xfc, 0xe4, 0x01, 0xc3, + 0x24, 0xda, 0x4c, 0xff, 0x10, 0x27, 0x78, 0xb0, 0x0b, 0x55, + 0x5c, 0xce, 0x62, 0x7d, 0x33, 0x2b, 0x25, 0x99, 0xaa, 0x99, + 0xea, 0xa3, 0x1d, 0xd8, 0x2b, 0x57, 0xb5, 0xe4, 0x04, 0x21, + 0x75, 0xd9, 0xc4, 0xd0, 0x3d, 0xa1, 0xa5, 0x8f +}; + u_int8_t sk_pld[] = { 0x21, 0x00, 0x01, 0x94, 0x14, 0x77, 0x25, 0x7b, 0x82, 0xc0, 0xdb, 0x0b, 0x24, 0x36, 0x36, 0x13, 0x36, 0xe4, 0x99, 0xad, @@ -441,6 +485,25 @@ parser_fuzz_tests(void) ASSERT_PTR_NE(data = ibuf_new(cookies, sizeof(cookies)), NULL); ASSERT_INT_EQ(ibuf_add(data, genhdr, sizeof(genhdr)), 0); set_length(ibuf_data(data), ibuf_size(data)); + print_hex(ibuf_data(data), 0, ibuf_size(data)); + prepare_header(, data); + prepare_message(, data); + ASSERT_INT_EQ(ikev2_pld_parse(NULL, , , 0), 0); + fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP | + FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | +
Re: iked(8): add support for IKEv2 Message Fragmentation
On 3/30/19 3:11 PM, Tobias Heider wrote: Hi Stuart, I'm glad to see people are using this. There's some smaller fixes that I haven't sent to the list yet, so probably I'll send an updated diff on monday. I plan to start using this patch this week, likely as soon as you send the updated diff. I started on the same feature in June of 2018, but other tasks took priority and it stalled. I have a pretty good testbed for this, as I have several site-to-site links that drop UDP fragments and several road warriors that would experience fragment drops depending on the cell network they use. I will report back on this thread with my findings. Thanks for the patch! -TimS Regards, Tobias On 3/30/19 6:43 PM, Stuart Henderson wrote: This diff hasn't gone anywhere recently - I've been using it since Tobias posted it with no problems. Any comments on whether it should go in, and if so, before/after 6.5? The feature is disabled by default. Index: config.c === RCS file: /cvs/src/sbin/iked/config.c,v retrieving revision 1.49 diff -u -p -r1.49 config.c --- config.c27 Nov 2017 18:39:35 - 1.49 +++ config.c30 Mar 2019 17:41:33 - @@ -94,12 +94,30 @@ config_free_kex(struct iked_kex *kex) } void +config_free_fragments(struct iked_frag *frag) +{ + size_t i; + if (frag && frag->frag_arr) { + for (i = 0; i < frag->frag_count; i++) { + free(frag->frag_arr[i]->frag_data); + frag->frag_arr[i]->frag_data = NULL; + free(frag->frag_arr[i]); + frag->frag_arr[i] = NULL; + } + free(frag->frag_arr); + frag->frag_arr = NULL; + bzero(frag, sizeof(struct iked_frag)); + } +} + +void config_free_sa(struct iked *env, struct iked_sa *sa) { timer_del(env, >sa_timer); timer_del(env, >sa_keepalive); timer_del(env, >sa_rekey); + config_free_fragments(>sa_fragments); config_free_proposals(>sa_proposals, 0); config_free_childsas(env, >sa_childsas, NULL, NULL); sa_free_flows(env, >sa_flows); @@ -925,6 +943,29 @@ config_setkeys(struct iked *env) EVP_PKEY_free(key); return (ret); +} + +int +config_setfragmentation(struct iked *env) +{ + unsigned int boolval; + + boolval = env->sc_frag; + proc_compose(>sc_ps, PROC_IKEV2, IMSG_CTL_FRAGMENTATION, + , sizeof(boolval)); + return (0); +} + +int +config_getfragmentation(struct iked *env, struct imsg *imsg) +{ + unsigned int boolval; + + IMSG_SIZE_CHECK(imsg, ); + memcpy(, imsg->data, sizeof(boolval)); + env->sc_frag = boolval; + log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); + return (0); } int Index: iked.c === RCS file: /cvs/src/sbin/iked/iked.c,v retrieving revision 1.36 diff -u -p -r1.36 iked.c --- iked.c 27 Nov 2017 18:39:35 - 1.36 +++ iked.c 30 Mar 2019 17:41:33 - @@ -251,6 +251,7 @@ parent_configure(struct iked *env) fatal("pledge"); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); @@ -282,6 +283,7 @@ parent_reload(struct iked *env, int rese config_setcompile(env, PROC_IKEV2); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); Index: iked.conf.5 === RCS file: /cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.53 diff -u -p -r1.53 iked.conf.5 --- iked.conf.5 31 Jan 2018 13:25:55 - 1.53 +++ iked.conf.5 30 Mar 2019 17:41:33 - @@ -136,6 +136,12 @@ This is the default. .It Ic set decouple Don't load the negotiated SAs and flows from the kernel. This mode is only useful for testing and debugging. +.It Ic set fragmentation +Enable IKEv2 Message Fragmentation (RFC 7383) support. +This allows IKEv2 to operate in environments that might block IP fragments. +.It Ic set nofragmentation +Disables IKEv2 Message Fragmentation support. +This is the default. .It Ic set mobike Enable MOBIKE (RFC 4555) support. This is the default. Index: iked.h === RCS file: /cvs/src/sbin/iked/iked.h,v retrieving revision 1.119 diff -u -p -r1.119 iked.h --- iked.h 6 Aug 2018 06:30:06 - 1.119 +++ iked.h 30 Mar 2019 17:41:33 - @@ -362,6 +362,21 @@ struct iked_kex { struct ibuf *kex_dhpeer;/* pointer to i or r */ };
Re: iked(8): add support for IKEv2 Message Fragmentation
Hi Stuart, I'm glad to see people are using this. There's some smaller fixes that I haven't sent to the list yet, so probably I'll send an updated diff on monday. Regards, Tobias On 3/30/19 6:43 PM, Stuart Henderson wrote: > This diff hasn't gone anywhere recently - I've been using it since > Tobias posted it with no problems. Any comments on whether it should > go in, and if so, before/after 6.5? The feature is disabled by default. > > Index: config.c > === > RCS file: /cvs/src/sbin/iked/config.c,v > retrieving revision 1.49 > diff -u -p -r1.49 config.c > --- config.c 27 Nov 2017 18:39:35 - 1.49 > +++ config.c 30 Mar 2019 17:41:33 - > @@ -94,12 +94,30 @@ config_free_kex(struct iked_kex *kex) > } > > void > +config_free_fragments(struct iked_frag *frag) > +{ > + size_t i; > + if (frag && frag->frag_arr) { > + for (i = 0; i < frag->frag_count; i++) { > + free(frag->frag_arr[i]->frag_data); > + frag->frag_arr[i]->frag_data = NULL; > + free(frag->frag_arr[i]); > + frag->frag_arr[i] = NULL; > + } > + free(frag->frag_arr); > + frag->frag_arr = NULL; > + bzero(frag, sizeof(struct iked_frag)); > + } > +} > + > +void > config_free_sa(struct iked *env, struct iked_sa *sa) > { > timer_del(env, >sa_timer); > timer_del(env, >sa_keepalive); > timer_del(env, >sa_rekey); > > + config_free_fragments(>sa_fragments); > config_free_proposals(>sa_proposals, 0); > config_free_childsas(env, >sa_childsas, NULL, NULL); > sa_free_flows(env, >sa_flows); > @@ -925,6 +943,29 @@ config_setkeys(struct iked *env) > EVP_PKEY_free(key); > > return (ret); > +} > + > +int > +config_setfragmentation(struct iked *env) > +{ > + unsigned int boolval; > + > + boolval = env->sc_frag; > + proc_compose(>sc_ps, PROC_IKEV2, IMSG_CTL_FRAGMENTATION, > + , sizeof(boolval)); > + return (0); > +} > + > +int > +config_getfragmentation(struct iked *env, struct imsg *imsg) > +{ > + unsigned int boolval; > + > + IMSG_SIZE_CHECK(imsg, ); > + memcpy(, imsg->data, sizeof(boolval)); > + env->sc_frag = boolval; > + log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); > + return (0); > } > > int > Index: iked.c > === > RCS file: /cvs/src/sbin/iked/iked.c,v > retrieving revision 1.36 > diff -u -p -r1.36 iked.c > --- iked.c27 Nov 2017 18:39:35 - 1.36 > +++ iked.c30 Mar 2019 17:41:33 - > @@ -251,6 +251,7 @@ parent_configure(struct iked *env) > fatal("pledge"); > > config_setmobike(env); > + config_setfragmentation(env); > config_setcoupled(env, env->sc_decoupled ? 0 : 1); > config_setmode(env, env->sc_passive ? 1 : 0); > config_setocsp(env); > @@ -282,6 +283,7 @@ parent_reload(struct iked *env, int rese > config_setcompile(env, PROC_IKEV2); > > config_setmobike(env); > + config_setfragmentation(env); > config_setcoupled(env, env->sc_decoupled ? 0 : 1); > config_setmode(env, env->sc_passive ? 1 : 0); > config_setocsp(env); > Index: iked.conf.5 > === > RCS file: /cvs/src/sbin/iked/iked.conf.5,v > retrieving revision 1.53 > diff -u -p -r1.53 iked.conf.5 > --- iked.conf.5 31 Jan 2018 13:25:55 - 1.53 > +++ iked.conf.5 30 Mar 2019 17:41:33 - > @@ -136,6 +136,12 @@ This is the default. > .It Ic set decouple > Don't load the negotiated SAs and flows from the kernel. > This mode is only useful for testing and debugging. > +.It Ic set fragmentation > +Enable IKEv2 Message Fragmentation (RFC 7383) support. > +This allows IKEv2 to operate in environments that might block IP fragments. > +.It Ic set nofragmentation > +Disables IKEv2 Message Fragmentation support. > +This is the default. > .It Ic set mobike > Enable MOBIKE (RFC 4555) support. > This is the default. > Index: iked.h > === > RCS file: /cvs/src/sbin/iked/iked.h,v > retrieving revision 1.119 > diff -u -p -r1.119 iked.h > --- iked.h6 Aug 2018 06:30:06 - 1.119 > +++ iked.h30 Mar 2019 17:41:33 - > @@ -362,6 +362,21 @@ struct iked_kex { > struct ibuf *kex_dhpeer;/* pointer to i or r */ > }; > > +struct iked_frag_entry { > + uint8_t *frag_data; > + size_t frag_size; > +}; > + > +struct iked_frag { > + struct iked_frag_entry **frag_arr; /* list of fragment > buffers */ > + size_tfrag_count; /* number of fragments > received */ > +#define IKED_FRAG_TOTAL_MAX 111 /* upper limit of
Re: iked(8): add support for IKEv2 Message Fragmentation
This diff hasn't gone anywhere recently - I've been using it since Tobias posted it with no problems. Any comments on whether it should go in, and if so, before/after 6.5? The feature is disabled by default. Index: config.c === RCS file: /cvs/src/sbin/iked/config.c,v retrieving revision 1.49 diff -u -p -r1.49 config.c --- config.c27 Nov 2017 18:39:35 - 1.49 +++ config.c30 Mar 2019 17:41:33 - @@ -94,12 +94,30 @@ config_free_kex(struct iked_kex *kex) } void +config_free_fragments(struct iked_frag *frag) +{ + size_t i; + if (frag && frag->frag_arr) { + for (i = 0; i < frag->frag_count; i++) { + free(frag->frag_arr[i]->frag_data); + frag->frag_arr[i]->frag_data = NULL; + free(frag->frag_arr[i]); + frag->frag_arr[i] = NULL; + } + free(frag->frag_arr); + frag->frag_arr = NULL; + bzero(frag, sizeof(struct iked_frag)); + } +} + +void config_free_sa(struct iked *env, struct iked_sa *sa) { timer_del(env, >sa_timer); timer_del(env, >sa_keepalive); timer_del(env, >sa_rekey); + config_free_fragments(>sa_fragments); config_free_proposals(>sa_proposals, 0); config_free_childsas(env, >sa_childsas, NULL, NULL); sa_free_flows(env, >sa_flows); @@ -925,6 +943,29 @@ config_setkeys(struct iked *env) EVP_PKEY_free(key); return (ret); +} + +int +config_setfragmentation(struct iked *env) +{ + unsigned int boolval; + + boolval = env->sc_frag; + proc_compose(>sc_ps, PROC_IKEV2, IMSG_CTL_FRAGMENTATION, + , sizeof(boolval)); + return (0); +} + +int +config_getfragmentation(struct iked *env, struct imsg *imsg) +{ + unsigned int boolval; + + IMSG_SIZE_CHECK(imsg, ); + memcpy(, imsg->data, sizeof(boolval)); + env->sc_frag = boolval; + log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); + return (0); } int Index: iked.c === RCS file: /cvs/src/sbin/iked/iked.c,v retrieving revision 1.36 diff -u -p -r1.36 iked.c --- iked.c 27 Nov 2017 18:39:35 - 1.36 +++ iked.c 30 Mar 2019 17:41:33 - @@ -251,6 +251,7 @@ parent_configure(struct iked *env) fatal("pledge"); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); @@ -282,6 +283,7 @@ parent_reload(struct iked *env, int rese config_setcompile(env, PROC_IKEV2); config_setmobike(env); + config_setfragmentation(env); config_setcoupled(env, env->sc_decoupled ? 0 : 1); config_setmode(env, env->sc_passive ? 1 : 0); config_setocsp(env); Index: iked.conf.5 === RCS file: /cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.53 diff -u -p -r1.53 iked.conf.5 --- iked.conf.5 31 Jan 2018 13:25:55 - 1.53 +++ iked.conf.5 30 Mar 2019 17:41:33 - @@ -136,6 +136,12 @@ This is the default. .It Ic set decouple Don't load the negotiated SAs and flows from the kernel. This mode is only useful for testing and debugging. +.It Ic set fragmentation +Enable IKEv2 Message Fragmentation (RFC 7383) support. +This allows IKEv2 to operate in environments that might block IP fragments. +.It Ic set nofragmentation +Disables IKEv2 Message Fragmentation support. +This is the default. .It Ic set mobike Enable MOBIKE (RFC 4555) support. This is the default. Index: iked.h === RCS file: /cvs/src/sbin/iked/iked.h,v retrieving revision 1.119 diff -u -p -r1.119 iked.h --- iked.h 6 Aug 2018 06:30:06 - 1.119 +++ iked.h 30 Mar 2019 17:41:33 - @@ -362,6 +362,21 @@ struct iked_kex { struct ibuf *kex_dhpeer;/* pointer to i or r */ }; +struct iked_frag_entry { + uint8_t *frag_data; + size_t frag_size; +}; + +struct iked_frag { + struct iked_frag_entry **frag_arr; /* list of fragment buffers */ + size_tfrag_count; /* number of fragments received */ +#define IKED_FRAG_TOTAL_MAX111 /* upper limit of frag_total (64kB / 576B) */ + size_tfrag_total; /* total numbe of fragments */ + size_tfrag_total_size; + uint8_t frag_nextpayload; + +}; + struct iked_sa { struct iked_sahdrsa_hdr; uint32_t sa_msgid; /* Last request rcvd */ @@ -377,6
Re: iked(8): add support for IKEv2 Message Fragmentation
On Wed, Feb 27, 2019 at 01:01:37PM +, Stuart Henderson wrote: > A couple of nits - manpage part is missing, I propose this: > > Index: iked.conf.5 > === > RCS file: /cvs/src/sbin/iked/iked.conf.5,v > retrieving revision 1.53 > diff -u -p -r1.53 iked.conf.5 > --- iked.conf.5 31 Jan 2018 13:25:55 - 1.53 > +++ iked.conf.5 27 Feb 2019 12:45:46 - > @@ -136,6 +136,12 @@ This is the default. > .It Ic set decouple > Don't load the negotiated SAs and flows from the kernel. > This mode is only useful for testing and debugging. > +.It Ic set fragmentation > +Enable IKEv2 Message Fragmentation (RFC 7383) support. > +This allows IKEv2 to operate in environments that might block IP fragments. > +.It Ic set nofragmentation > +Disables IKEv2 Message Fragmentation support. > +This is the default. > .It Ic set mobike > Enable MOBIKE (RFC 4555) support. > This is the default. +1, nothing more to say here. > There are some over-long lines - it's not fair to require <=80 for > everything in this diff when big parts of iked already exceed this, > but some of the longer ones need reining in e.g. > > > Index: sbin/iked/iked.h > .. > > |--| > > +#define IKED_FRAG_TOTAL_MAX111 /* upper limit > > of frag_total (64kB / 576B) */ > ...#define IKED_FRAG_TOTAL_MAX111 /* upper limit of frag_total > (64kB / 576B) */ > > > struct iked_message * > > ikev2_msg_lookup(struct iked *, struct iked_msgqueue *, > > struct iked_message *, struct ike_header *); > > +voidikev2_msg_lookup_dispose_all(struct iked *env, struct > > iked_msgqueue *queue, > > + struct iked_message *msg, struct ike_header *hdr); > > +int ikev2_msg_lookup_retransmit_all(struct iked *env, struct > > iked_msgqueue *queue, > > + struct iked_message *msg, struct ike_header *hdr, struct iked_sa > > *sa); > ...(split onto another line) > > > Index: sbin/iked/ikev2.c > .. > > - if ((m = ikev2_msg_lookup(env, >sa_responses, msg, hdr))) { > > - if (ikev2_msg_retransmit_response(env, sa, m)) { > > + if ((r = ikev2_msg_lookup_retransmit_all(env, > > >sa_responses, msg, hdr, sa)) != 0) { > > + if (r == -1) { > ...(and here) > > I've done that in my tree. Nice reminder to copy my vimrc to the machine next time, thx. > Ha, nice :) You're welcome ;)
Re: iked(8): add support for IKEv2 Message Fragmentation
On Wed, Feb 27, 2019 at 01:01:37PM +, Stuart Henderson wrote: > On 2019/02/26 16:34, Tobias Heider wrote: > > Hi, > > > > this diff adds support for IKEv2 Message Fragmentation as defined in > > RFC 7383 (https://tools.ietf.org/html/rfc7383) to iked(8). > > Thank you, I know there are quite a few additions in the genua tree and > splitting them out is not easy. I'm running this in a few places now, > have tested both with and without fragmentation, no problems seen. Actually, this is not even part of the genua tree. He implemented it here the last two weeks and tested it using bluhm@'s test machines. :) Patrick > A couple of nits - manpage part is missing, I propose this: > > Index: iked.conf.5 > === > RCS file: /cvs/src/sbin/iked/iked.conf.5,v > retrieving revision 1.53 > diff -u -p -r1.53 iked.conf.5 > --- iked.conf.5 31 Jan 2018 13:25:55 - 1.53 > +++ iked.conf.5 27 Feb 2019 12:45:46 - > @@ -136,6 +136,12 @@ This is the default. > .It Ic set decouple > Don't load the negotiated SAs and flows from the kernel. > This mode is only useful for testing and debugging. > +.It Ic set fragmentation > +Enable IKEv2 Message Fragmentation (RFC 7383) support. > +This allows IKEv2 to operate in environments that might block IP fragments. > +.It Ic set nofragmentation > +Disables IKEv2 Message Fragmentation support. > +This is the default. > .It Ic set mobike > Enable MOBIKE (RFC 4555) support. > This is the default. > > There are some over-long lines - it's not fair to require <=80 for > everything in this diff when big parts of iked already exceed this, > but some of the longer ones need reining in e.g. > > > Index: sbin/iked/iked.h > .. > > |--| > > +#define IKED_FRAG_TOTAL_MAX111 /* upper limit > > of frag_total (64kB / 576B) */ > ...#define IKED_FRAG_TOTAL_MAX111 /* upper limit of frag_total > (64kB / 576B) */ > > > struct iked_message * > > ikev2_msg_lookup(struct iked *, struct iked_msgqueue *, > > struct iked_message *, struct ike_header *); > > +voidikev2_msg_lookup_dispose_all(struct iked *env, struct > > iked_msgqueue *queue, > > + struct iked_message *msg, struct ike_header *hdr); > > +int ikev2_msg_lookup_retransmit_all(struct iked *env, struct > > iked_msgqueue *queue, > > + struct iked_message *msg, struct ike_header *hdr, struct iked_sa > > *sa); > ...(split onto another line) > > > Index: sbin/iked/ikev2.c > .. > > - if ((m = ikev2_msg_lookup(env, >sa_responses, msg, hdr))) { > > - if (ikev2_msg_retransmit_response(env, sa, m)) { > > + if ((r = ikev2_msg_lookup_retransmit_all(env, > > >sa_responses, msg, hdr, sa)) != 0) { > > + if (r == -1) { > ...(and here) > > I've done that in my tree. > > Are there comments from anyone else? >
Re: iked(8): add support for IKEv2 Message Fragmentation
On 2019/02/26 16:34, Tobias Heider wrote: > Hi, > > this diff adds support for IKEv2 Message Fragmentation as defined in > RFC 7383 (https://tools.ietf.org/html/rfc7383) to iked(8). Thank you, I know there are quite a few additions in the genua tree and splitting them out is not easy. I'm running this in a few places now, have tested both with and without fragmentation, no problems seen. A couple of nits - manpage part is missing, I propose this: Index: iked.conf.5 === RCS file: /cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.53 diff -u -p -r1.53 iked.conf.5 --- iked.conf.5 31 Jan 2018 13:25:55 - 1.53 +++ iked.conf.5 27 Feb 2019 12:45:46 - @@ -136,6 +136,12 @@ This is the default. .It Ic set decouple Don't load the negotiated SAs and flows from the kernel. This mode is only useful for testing and debugging. +.It Ic set fragmentation +Enable IKEv2 Message Fragmentation (RFC 7383) support. +This allows IKEv2 to operate in environments that might block IP fragments. +.It Ic set nofragmentation +Disables IKEv2 Message Fragmentation support. +This is the default. .It Ic set mobike Enable MOBIKE (RFC 4555) support. This is the default. There are some over-long lines - it's not fair to require <=80 for everything in this diff when big parts of iked already exceed this, but some of the longer ones need reining in e.g. > Index: sbin/iked/iked.h .. |--| > +#define IKED_FRAG_TOTAL_MAX 111 /* upper limit of > frag_total (64kB / 576B) */ ...#define IKED_FRAG_TOTAL_MAX 111 /* upper limit of frag_total (64kB / 576B) */ > struct iked_message * >ikev2_msg_lookup(struct iked *, struct iked_msgqueue *, > struct iked_message *, struct ike_header *); > +void ikev2_msg_lookup_dispose_all(struct iked *env, struct iked_msgqueue > *queue, > + struct iked_message *msg, struct ike_header *hdr); > +int ikev2_msg_lookup_retransmit_all(struct iked *env, struct iked_msgqueue > *queue, > + struct iked_message *msg, struct ike_header *hdr, struct iked_sa > *sa); ...(split onto another line) > Index: sbin/iked/ikev2.c .. > - if ((m = ikev2_msg_lookup(env, >sa_responses, msg, hdr))) { > - if (ikev2_msg_retransmit_response(env, sa, m)) { > + if ((r = ikev2_msg_lookup_retransmit_all(env, > >sa_responses, msg, hdr, sa)) != 0) { > + if (r == -1) { ...(and here) I've done that in my tree. Are there comments from anyone else?