Use a connection specific option to en-/disable IKEv1 fragmentation
authorTobias Brunner <tobias@strongswan.org>
Mon, 24 Dec 2012 11:28:01 +0000 (12:28 +0100)
committerTobias Brunner <tobias@strongswan.org>
Mon, 24 Dec 2012 12:00:01 +0000 (13:00 +0100)
25 files changed:
man/ipsec.conf.5.in
man/strongswan.conf.5.in
src/charon-nm/nm/nm_service.c
src/conftest/config.c
src/frontends/android/jni/libandroidbridge/backend/android_service.c
src/libcharon/config/ike_cfg.c
src/libcharon/config/ike_cfg.h
src/libcharon/plugins/android/android_service.c
src/libcharon/plugins/ha/ha_tunnel.c
src/libcharon/plugins/load_tester/load_tester_config.c
src/libcharon/plugins/maemo/maemo_service.c
src/libcharon/plugins/medcli/medcli_config.c
src/libcharon/plugins/medsrv/medsrv_config.c
src/libcharon/plugins/sql/sql_config.c
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/plugins/uci/uci_config.c
src/libcharon/sa/ikev1/task_manager_v1.c
src/libcharon/sa/ikev1/tasks/isakmp_vendor.c
src/starter/args.c
src/starter/confread.c
src/starter/confread.h
src/starter/keywords.h
src/starter/keywords.txt
src/starter/starterstroke.c
src/stroke/stroke_msg.h

index 303fb78..01c7c38 100644 (file)
@@ -403,6 +403,16 @@ force UDP encapsulation for ESP packets even if no NAT situation is detected.
 This may help to surmount restrictive firewalls. In order to force the peer to
 encapsulate packets, NAT detection payloads are faked.
 .TP
+.BR fragmentation " = yes | " no
+whether to use IKE fragmentation (proprietary IKEv1 extension).  Acceptable
+values are
+.B yes
+and
+.B no
+(the default). Fragmented messages sent by a peer are always accepted
+irrespective of the value of this option. If enabled, and the peer supports it,
+larger IKE messages will be sent in fragments.
+.TP
 .BR ike " = <cipher suites>"
 comma-separated list of IKE/ISAKMP SA encryption/authentication algorithms
 to be used, e.g.
index 14caccb..8000951 100644 (file)
@@ -178,11 +178,6 @@ openly transmitted hash of the PSK)
 .BR charon.ignore_routing_tables
 A space-separated list of routing tables to be excluded from route lookups
 .TP
-.BR charon.ike_fragmentation " [no]"
-Enables IKE fragmentation (proprietary IKEv1 extension). Fragmented messages
-are always accepted irrespective of the value of this option. If the peer
-supports it larger messages will be sent in fragments.
-.TP
 .BR charon.ikesa_table_segments " [1]"
 Number of exclusively locked segments in the hash table
 .TP
index 6fa5e51..7eb5e85 100644 (file)
@@ -500,7 +500,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
         */
        ike_cfg = ike_cfg_create(IKEV2, TRUE, encap, "0.0.0.0", FALSE,
                                                         charon->socket->get_port(charon->socket, FALSE),
-                                                       (char*)address, FALSE, IKEV2_UDP_PORT);
+                                                       (char*)address, FALSE, IKEV2_UDP_PORT, FALSE);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        peer_cfg = peer_cfg_create(priv->name, ike_cfg,
                                        CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
index f896b95..e270546 100644 (file)
@@ -106,7 +106,7 @@ static ike_cfg_t *load_ike_config(private_config_t *this,
                settings->get_str(settings, "configs.%s.lhost", "%any", config), FALSE,
                settings->get_int(settings, "configs.%s.lport", 500, config),
                settings->get_str(settings, "configs.%s.rhost", "%any", config), FALSE,
-               settings->get_int(settings, "configs.%s.rport", 500, config));
+               settings->get_int(settings, "configs.%s.rport", 500, config), FALSE);
        token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
        if (token)
        {
index 6c23bf2..f7fe290 100644 (file)
@@ -471,7 +471,7 @@ static job_requeue_t initiate(private_android_service_t *this)
 
        ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0", FALSE,
                                                         charon->socket->get_port(charon->socket, FALSE),
-                                                        this->gateway, FALSE, IKEV2_UDP_PORT);
+                                                        this->gateway, FALSE, IKEV2_UDP_PORT, FALSE);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
 
        peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
index 1006fc2..e87b47e 100644 (file)
@@ -90,6 +90,11 @@ struct private_ike_cfg_t {
        bool force_encap;
 
        /**
+        * use IKEv1 fragmentation
+        */
+       bool fragmentation;
+
+       /**
         * List of proposals to use
         */
        linked_list_t *proposals;
@@ -113,6 +118,12 @@ METHOD(ike_cfg_t, force_encap_, bool,
        return this->force_encap;
 }
 
+METHOD(ike_cfg_t, fragmentation, bool,
+       private_ike_cfg_t *this)
+{
+       return this->fragmentation;
+}
+
 METHOD(ike_cfg_t, get_my_addr, char*,
        private_ike_cfg_t *this, bool *allow_any)
 {
@@ -268,6 +279,7 @@ METHOD(ike_cfg_t, equals, bool,
                this->version == other->version &&
                this->certreq == other->certreq &&
                this->force_encap == other->force_encap &&
+               this->fragmentation == other->fragmentation &&
                streq(this->me, other->me) &&
                streq(this->other, other->other) &&
                this->my_port == other->my_port &&
@@ -299,7 +311,8 @@ METHOD(ike_cfg_t, destroy, void,
  */
 ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
                                                  char *me, bool my_allow_any, u_int16_t my_port,
-                                                 char *other, bool other_allow_any, u_int16_t other_port)
+                                                 char *other, bool other_allow_any, u_int16_t other_port,
+                                                 bool fragmentation)
 {
        private_ike_cfg_t *this;
 
@@ -308,6 +321,7 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
                        .get_version = _get_version,
                        .send_certreq = _send_certreq,
                        .force_encap = _force_encap_,
+                       .fragmentation = _fragmentation,
                        .get_my_addr = _get_my_addr,
                        .get_other_addr = _get_other_addr,
                        .get_my_port = _get_my_port,
@@ -324,6 +338,7 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
                .version = version,
                .certreq = certreq,
                .force_encap = force_encap,
+               .fragmentation = fragmentation,
                .me = strdup(me),
                .other = strdup(other),
                .my_allow_any = my_allow_any,
index fa2aaa3..0c44842 100644 (file)
@@ -134,11 +134,18 @@ struct ike_cfg_t {
        /**
         * Enforce UDP encapsulation by faking NATD notifies?
         *
-        * @return                              TRUE to enfoce UDP encapsulation
+        * @return                              TRUE to enforce UDP encapsulation
         */
        bool (*force_encap) (ike_cfg_t *this);
 
        /**
+        * Use proprietary IKEv1 fragmentation
+        *
+        * @return                              TRUE to use fragmentation
+        */
+       bool (*fragmentation) (ike_cfg_t *this);
+
+       /**
         * Get the DH group to use for IKE_SA setup.
         *
         * @return                              dh group to use for initialization
@@ -183,10 +190,12 @@ struct ike_cfg_t {
  * @param other                                address/DNS name of remote peer
  * @param other_allow_any      allow override of remote address by any address
  * @param other_port           IKE port to use as dest, 500 uses IKEv2 port floating
+ * @param fragmentation                use IKEv1 fragmentation
  * @return                                     ike_cfg_t object.
  */
 ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
                                                  char *me, bool my_allow_any, u_int16_t my_port,
-                                                 char *other, bool other_allow_any, u_int16_t other_port);
+                                                 char *other, bool other_allow_any, u_int16_t other_port,
+                                                 bool fragmentation);
 
 #endif /** IKE_CFG_H_ @}*/
index d398b13..0188b0c 100644 (file)
@@ -266,7 +266,7 @@ static job_requeue_t initiate(private_android_service_t *this)
 
        ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE,
                                                         charon->socket->get_port(charon->socket, FALSE),
-                                                        hostname, FALSE, IKEV2_UDP_PORT);
+                                                        hostname, FALSE, IKEV2_UDP_PORT, FALSE);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
 
        peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
index 05f522e..e7db1ff 100644 (file)
@@ -205,7 +205,7 @@ static void setup_tunnel(private_ha_tunnel_t *this,
        /* create config and backend */
        ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local, FALSE,
                                                         charon->socket->get_port(charon->socket, FALSE),
-                                                        remote, FALSE, IKEV2_UDP_PORT);
+                                                        remote, FALSE, IKEV2_UDP_PORT, FALSE);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        peer_cfg = peer_cfg_create("ha", ike_cfg, CERT_NEVER_SEND,
                                                UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE, 30,
index 9e16156..a9d399b 100644 (file)
@@ -490,14 +490,14 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
        {
                ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
                                                                 local, FALSE, this->port + num - 1,
-                                                                remote, FALSE, IKEV2_NATT_PORT);
+                                                                remote, FALSE, IKEV2_NATT_PORT, FALSE);
        }
        else
        {
                ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
                                                                 local, FALSE,
                                                                 charon->socket->get_port(charon->socket, FALSE),
-                                                                remote, FALSE, IKEV2_UDP_PORT);
+                                                                remote, FALSE, IKEV2_UDP_PORT, FALSE);
        }
        ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
        peer_cfg = peer_cfg_create("load-test", ike_cfg,
index dca01fb..759bd96 100644 (file)
@@ -325,7 +325,7 @@ static gboolean initiate_connection(private_maemo_service_t *this,
 
        ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE,
                                                         charon->socket->get_port(charon->socket, FALSE),
-                                                        hostname, FALSE, IKEV2_UDP_PORT);
+                                                        hostname, FALSE, IKEV2_UDP_PORT, FALSE);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
 
        peer_cfg = peer_cfg_create(this->current, ike_cfg,
index 42c1582..12ffc1a 100644 (file)
@@ -105,7 +105,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
        ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
                                                         "0.0.0.0", FALSE,
                                                         charon->socket->get_port(charon->socket, FALSE),
-                                                        address, FALSE, IKEV2_UDP_PORT);
+                                                        address, FALSE, IKEV2_UDP_PORT, FALSE);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        med_cfg = peer_cfg_create(
                "mediation", ike_cfg,
@@ -380,7 +380,7 @@ medcli_config_t *medcli_config_create(database_t *db)
                .ike = ike_cfg_create(IKEV2, FALSE, FALSE,
                                                          "0.0.0.0", FALSE,
                                                          charon->socket->get_port(charon->socket, FALSE),
-                                                         "0.0.0.0", FALSE, IKEV2_UDP_PORT),
+                                                         "0.0.0.0", FALSE, IKEV2_UDP_PORT, FALSE),
        );
        this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
 
index a2d7489..d167581 100644 (file)
@@ -142,7 +142,7 @@ medsrv_config_t *medsrv_config_create(database_t *db)
                .ike = ike_cfg_create(IKEV2, FALSE, FALSE,
                                                          "0.0.0.0", FALSE,
                                                          charon->socket->get_port(charon->socket, FALSE),
-                                                         "0.0.0.0", FALSE, IKEV2_UDP_PORT),
+                                                         "0.0.0.0", FALSE, IKEV2_UDP_PORT, FALSE),
        );
        this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
 
index 565c858..44a593c 100644 (file)
@@ -261,7 +261,7 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
                ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap,
                                                                 local, FALSE,
                                                                 charon->socket->get_port(charon->socket, FALSE),
-                                                                remote, FALSE, IKEV2_UDP_PORT);
+                                                                remote, FALSE, IKEV2_UDP_PORT, FALSE);
                add_ike_proposals(this, ike_cfg, id);
                return ike_cfg;
        }
index de3f447..0ab94f2 100644 (file)
@@ -233,7 +233,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
                                                         ikeport,
                                                         msg->add_conn.other.address,
                                                         msg->add_conn.other.allow_any,
-                                                        msg->add_conn.other.ikeport);
+                                                        msg->add_conn.other.ikeport,
+                                                        msg->add_conn.fragmentation);
        add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
        return ike_cfg;
 }
index 76dce12..6dae14e 100644 (file)
@@ -155,7 +155,7 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
                ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
                                                                 local_addr, FALSE,
                                                                 charon->socket->get_port(charon->socket, FALSE),
-                                                                remote_addr, FALSE, IKEV2_UDP_PORT);
+                                                                remote_addr, FALSE, IKEV2_UDP_PORT, FALSE);
                ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
                this->peer_cfg = peer_cfg_create(
                                        name, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO,
@@ -253,7 +253,7 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool,
                this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
                                                                local_addr, FALSE,
                                                                charon->socket->get_port(charon->socket, FALSE),
-                                                               remote_addr, FALSE, IKEV2_UDP_PORT);
+                                                               remote_addr, FALSE, IKEV2_UDP_PORT, FALSE);
                this->ike_cfg->add_proposal(this->ike_cfg,
                                                                        create_proposal(ike_proposal, PROTO_IKE));
 
index 606a981..320aa5e 100644 (file)
@@ -226,11 +226,6 @@ struct private_task_manager_t {
        } frag;
 
        /**
-        * TRUE if fragmentation (as sender) is enabled in config
-        */
-       bool fragmentation;
-
-       /**
         * List of queued tasks not yet in action
         */
        linked_list_t *queued_tasks;
@@ -411,12 +406,14 @@ static bool send_fragment(private_task_manager_t *this, bool request,
 static bool send_packet(private_task_manager_t *this, bool request,
                                                packet_t *packet)
 {
+       ike_cfg_t *ike_cfg;
        host_t *src, *dst;
        chunk_t data;
 
+       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
        data = packet->get_data(packet);
        if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_FRAGMENTATION) &&
-               this->fragmentation && data.len > MAX_FRAGMENT_SIZE)
+               ike_cfg->fragmentation(ike_cfg) && data.len > MAX_FRAGMENT_SIZE)
        {
                fragment_payload_t *fragment;
                u_int8_t num, count;
@@ -2001,8 +1998,6 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
                                        "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, charon->name),
                .retransmit_base = lib->settings->get_double(lib->settings,
                                        "%s.retransmit_base", RETRANSMIT_BASE, charon->name),
-               .fragmentation = lib->settings->get_bool(lib->settings,
-                                       "%s.ike_fragmentation", FALSE, charon->name),
        );
 
        if (!this->rng)
index f83f114..32eeee3 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2012 Tobias Brunner
  * Copyright (C) 2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -156,14 +157,15 @@ METHOD(task_t, build, status_t,
 {
        vendor_id_payload_t *vid_payload;
        bool strongswan, cisco_unity, fragmentation;
+       ike_cfg_t *ike_cfg;
        int i;
 
        strongswan = lib->settings->get_bool(lib->settings,
                                                                "%s.send_vendor_id", FALSE, charon->name);
        cisco_unity = lib->settings->get_bool(lib->settings,
                                                                "%s.cisco_unity", FALSE, charon->name);
-       fragmentation = lib->settings->get_bool(lib->settings,
-                                                               "%s.ike_fragmentation", FALSE, charon->name);
+       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
+       fragmentation = ike_cfg->fragmentation(ike_cfg);
        if (!this->initiator && fragmentation)
        {
                fragmentation = this->ike_sa->supports_extension(this->ike_sa,
index 1c16e0b..ad73a16 100644 (file)
@@ -138,6 +138,7 @@ static const token_info_t token_info[] =
        { ARG_STR,  offsetof(starter_conn_t, aaa_identity), NULL                       },
        { ARG_MISC, 0, NULL  /* KW_MOBIKE */                                           },
        { ARG_MISC, 0, NULL  /* KW_FORCEENCAPS */                                      },
+       { ARG_MISC, 0, NULL  /* KW_FRAGMENTATION */                                    },
        { ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL                },
        { ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL              },
        { ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL                    },
index fecb998..dfe7e2c 100644 (file)
@@ -567,6 +567,9 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
                case KW_FORCEENCAPS:
                        KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FORCE_ENCAP)
                        break;
+               case KW_FRAGMENTATION:
+                       KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FRAGMENTATION)
+                       break;
                case KW_MODECONFIG:
                        KW_SA_OPTION_FLAG("push", "pull", SA_OPTION_MODECFG_PUSH)
                        break;
index 3f20798..5e0e0f2 100644 (file)
@@ -81,6 +81,7 @@ typedef enum {
                SA_OPTION_XAUTH_SERVER  = 1 << 5, /* are we an XAUTH server? */
                SA_OPTION_MOBIKE                = 1 << 6, /* enable MOBIKE for IKEv2  */
                SA_OPTION_FORCE_ENCAP   = 1 << 7, /* force UDP encapsulation */
+               SA_OPTION_FRAGMENTATION = 1 << 8, /* enable IKEv1 fragmentation */
 } sa_option_t;
 
 typedef struct starter_end starter_end_t;
index 537bceb..f776f33 100644 (file)
@@ -42,6 +42,7 @@ typedef enum {
        KW_AAA_IDENTITY,
        KW_MOBIKE,
        KW_FORCEENCAPS,
+       KW_FRAGMENTATION,
        KW_IKELIFETIME,
        KW_KEYLIFE,
        KW_REKEYMARGIN,
index 8366f52..1f16412 100644 (file)
@@ -40,6 +40,7 @@ eap_identity,      KW_EAP_IDENTITY
 aaa_identity,      KW_AAA_IDENTITY
 mobike,                   KW_MOBIKE
 forceencaps,       KW_FORCEENCAPS
+fragmentation,     KW_FRAGMENTATION
 ikelifetime,       KW_IKELIFETIME
 lifetime,          KW_KEYLIFE
 keylife,           KW_KEYLIFE
index 68e6fd5..4128853 100644 (file)
@@ -180,6 +180,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
        }
        msg.add_conn.mobike = conn->options & SA_OPTION_MOBIKE;
        msg.add_conn.force_encap = conn->options & SA_OPTION_FORCE_ENCAP;
+       msg.add_conn.fragmentation = conn->options & SA_OPTION_FRAGMENTATION;
        msg.add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
        msg.add_conn.install_policy = conn->install_policy;
        msg.add_conn.aggressive = conn->aggressive;
index 1ce44f9..e972a59 100644 (file)
@@ -254,6 +254,7 @@ struct stroke_msg_t {
                        int mobike;
                        int aggressive;
                        int force_encap;
+                       int fragmentation;
                        int ipcomp;
                        time_t inactivity;
                        int proxy_mode;