IPComp for IKEv2
authorTobias Brunner <tobias@strongswan.org>
Thu, 8 May 2008 16:19:11 +0000 (16:19 -0000)
committerTobias Brunner <tobias@strongswan.org>
Thu, 8 May 2008 16:19:11 +0000 (16:19 -0000)
15 files changed:
src/charon/config/child_cfg.c
src/charon/config/child_cfg.h
src/charon/encoding/payloads/notify_payload.c
src/charon/kernel/kernel_interface.c
src/charon/kernel/kernel_interface.h
src/charon/plugins/sql/mysql.sql
src/charon/plugins/sql/sql_config.c
src/charon/plugins/sql/sqlite.sql
src/charon/plugins/stroke/stroke_config.c
src/charon/sa/child_sa.c
src/charon/sa/child_sa.h
src/charon/sa/ike_sa.c
src/charon/sa/tasks/child_create.c
src/starter/starterstroke.c
src/stroke/stroke_msg.h

index 2c72019..33dd73c 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2008 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -34,6 +35,15 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART,
        "ACTION_RESTART",
 );
 
+ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE, 
+       "IPCOMP_NONE");
+ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE,
+       "IPCOMP_OUI",
+       "IPCOMP_DEFLATE",
+       "IPCOMP_LZS",
+       "IPCOMP_LZJH");
+ENUM_END(ipcomp_transform_names, IPCOMP_LZJH);
+
 typedef struct private_child_cfg_t private_child_cfg_t;
 
 /**
@@ -111,6 +121,11 @@ struct private_child_cfg_t {
         * substracted from rekeytime.
         */
        u_int32_t jitter;
+       
+       /**
+        * enable IPComp
+        */
+       bool use_ipcomp;
 };
 
 /**
@@ -399,6 +414,14 @@ static diffie_hellman_group_t get_dh_group(private_child_cfg_t *this)
 }
 
 /**
+ * Implementation of child_cfg_t.use_ipcomp.
+ */
+static bool use_ipcomp(private_child_cfg_t *this)
+{
+       return this->use_ipcomp;
+}
+
+/**
  * Implementation of child_cfg_t.get_name
  */
 static child_cfg_t* get_ref(private_child_cfg_t *this)
@@ -432,7 +455,7 @@ static void destroy(private_child_cfg_t *this)
 child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
                                                          u_int32_t rekeytime, u_int32_t jitter,
                                                          char *updown, bool hostaccess, mode_t mode,
-                                                         action_t dpd_action, action_t close_action)
+                                                         action_t dpd_action, action_t close_action, bool ipcomp)
 {
        private_child_cfg_t *this = malloc_thing(private_child_cfg_t);
 
@@ -449,6 +472,7 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
        this->public.get_close_action = (action_t (*) (child_cfg_t *))get_close_action;
        this->public.get_lifetime = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime;
        this->public.get_dh_group = (diffie_hellman_group_t(*)(child_cfg_t*)) get_dh_group;
+       this->public.use_ipcomp = (bool (*) (child_cfg_t *))use_ipcomp;
        this->public.get_ref = (child_cfg_t* (*) (child_cfg_t*))get_ref;
        this->public.destroy = (void (*) (child_cfg_t*))destroy;
        
@@ -461,6 +485,7 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
        this->mode = mode;
        this->dpd_action = dpd_action;
        this->close_action = close_action;
+       this->use_ipcomp = ipcomp; 
        this->refcount = 1;
        this->proposals = linked_list_create();
        this->my_ts = linked_list_create();
index 3d4889b..228f0d8 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2008 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -26,6 +27,7 @@
 
 typedef enum mode_t mode_t;
 typedef enum action_t action_t;
+typedef enum ipcomp_transform_t ipcomp_transform_t;
 typedef struct child_cfg_t child_cfg_t;
 
 #include <library.h>
@@ -69,6 +71,22 @@ enum action_t {
 extern enum_name_t *action_names;
 
 /**
+ * IPComp transform IDs, as in RFC 4306
+ */
+enum ipcomp_transform_t {
+       IPCOMP_NONE = 241,
+       IPCOMP_OUI = 1,
+       IPCOMP_DEFLATE = 2,
+       IPCOMP_LZS = 3,
+       IPCOMP_LZJH = 4,
+};
+
+/**
+ * enum strings for ipcomp_transform_t.
+ */
+extern enum_name_t *ipcomp_transform_names;
+
+/**
  * A child_cfg_t defines the config template for a CHILD_SA.
  *
  * After creation, proposals and traffic selectors may be added to the config.
@@ -214,6 +232,14 @@ struct child_cfg_t {
        diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this);
        
        /**
+        * Check whether IPComp should be used, if the other peer supports it.
+        * 
+        * @return                              TRUE, if IPComp should be used
+        *                                              FALSE, otherwise
+        */
+       bool (*use_ipcomp)(child_cfg_t *this);
+       
+       /**
         * Increase the reference count.
         *
         * @return                              reference to this
@@ -247,12 +273,14 @@ struct child_cfg_t {
  * @param hostaccess           TRUE to allow access to the local host
  * @param mode                         mode to propose for CHILD_SA, transport, tunnel or BEET
  * @param dpd_action           DPD action
- * @param close_action         lose action
+ * @param close_action         close action
+ * @param ipcomp                       use IPComp, if peer supports it
  * @return                                     child_cfg_t object
  */
 child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
                                                          u_int32_t rekeytime, u_int32_t jitter,
                                                          char *updown, bool hostaccess, mode_t mode,
-                                                         action_t dpd_action, action_t close_action);
+                                                         action_t dpd_action, action_t close_action,
+                                                         bool ipcomp);
 
 #endif /* CHILD_CFG_H_ @} */
index ec22d06..6bf260d 100644 (file)
@@ -332,6 +332,14 @@ static status_t verify(private_notify_payload_t *this)
                        }
                        break;
                }
+               case IPCOMP_SUPPORTED:
+               {
+                       if (this->notification_data.len != 3)
+                       {
+                               bad_length = TRUE;
+                       }
+                       break;
+               }
                case ME_ENDPOINT:
                        if (this->notification_data.len != 8 &&
                                this->notification_data.len != 12 &&
index b1cabfa..43837a2 100644 (file)
@@ -1,6 +1,6 @@
 /*
+ * Copyright (C) 2006-2008 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005 Jan Hutter
@@ -143,6 +143,17 @@ static kernel_algorithm_t integrity_algs[] = {
 };
 
 /**
+ * Algorithms for IPComp
+ */
+static kernel_algorithm_t compression_algs[] = {
+/*     {IPCOMP_OUI,                    "***",                  0}, */
+       {IPCOMP_DEFLATE,                "deflate",              0},
+       {IPCOMP_LZS,                    "lzs",                  0},
+       {IPCOMP_LZJH,                   "lzjh",                 0},
+       {END_OF_LIST,                   NULL,                   0},
+};
+
+/**
  * Look up a kernel algorithm name and its key size
  */
 static char* lookup_algorithm(kernel_algorithm_t *kernel_algo, 
@@ -153,8 +164,8 @@ static char* lookup_algorithm(kernel_algorithm_t *kernel_algo,
                if (ikev2_algo == kernel_algo->ikev2_id)
                {
                        /* match, evaluate key length */
-                       if (*key_size == 0)
-                       {       /* update key size of not set */
+                       if (key_size && *key_size == 0)
+                       {       /* update key size if not set */
                                *key_size = kernel_algo->key_size;
                        }
                        return kernel_algo->name;
@@ -518,11 +529,20 @@ static void process_expire(private_kernel_interface_t *this, struct nlmsghdr *hd
        struct xfrm_user_expire *expire;
        
        expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr);
-       protocol = expire->state.id.proto == KERNEL_ESP ? PROTO_ESP : PROTO_AH;
+       protocol = expire->state.id.proto;
+       protocol = (protocol == KERNEL_ESP) ? PROTO_ESP : (protocol == KERNEL_AH) ? PROTO_AH : protocol;
        spi = expire->state.id.spi;
        reqid = expire->state.reqid;
        
        DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
+       
+       if (protocol != PROTO_ESP && protocol != PROTO_AH)
+       {
+               DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA 0x%x (reqid %d) which is "
+                               "not a CHILD_SA", ntohl(spi), reqid);
+               return;
+       }
+       
        DBG1(DBG_KNL, "creating %s job for %N CHILD_SA 0x%x (reqid %d)",
                 expire->hard ? "delete" : "rekey",  protocol_id_names,
                 protocol, ntohl(spi), reqid);
@@ -1814,12 +1834,11 @@ static status_t del_ip(private_kernel_interface_t *this, host_t *virtual_ip)
 }
 
 /**
- * Implementation of kernel_interface_t.get_spi.
+ * Get an SPI for a specific protocol from the kernel.
  */
-static status_t get_spi(private_kernel_interface_t *this, 
-                                               host_t *src, host_t *dst, 
-                                               protocol_id_t protocol, u_int32_t reqid,
-                                               u_int32_t *spi)
+static status_t get_spi_internal(private_kernel_interface_t *this,
+               host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
+               u_int32_t reqid, u_int32_t *spi)
 {
        unsigned char request[BUFFER_SIZE];
        struct nlmsghdr *hdr, *out;
@@ -1829,8 +1848,6 @@ static status_t get_spi(private_kernel_interface_t *this,
        
        memset(&request, 0, sizeof(request));
        
-       DBG2(DBG_KNL, "getting SPI for reqid %d", reqid);
-       
        hdr = (struct nlmsghdr*)request;
        hdr->nlmsg_flags = NLM_F_REQUEST;
        hdr->nlmsg_type = XFRM_MSG_ALLOCSPI;
@@ -1839,12 +1856,12 @@ static status_t get_spi(private_kernel_interface_t *this,
        userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr);
        host2xfrm(src, &userspi->info.saddr);
        host2xfrm(dst, &userspi->info.id.daddr);
-       userspi->info.id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+       userspi->info.id.proto = proto;
        userspi->info.mode = TRUE; /* tunnel mode */
        userspi->info.reqid = reqid;
        userspi->info.family = src->get_family(src);
-       userspi->min = 0xc0000000;
-       userspi->max = 0xcFFFFFFF;
+       userspi->min = min;
+       userspi->max = max;
        
        if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
        {
@@ -1880,13 +1897,57 @@ static status_t get_spi(private_kernel_interface_t *this,
        
        if (received_spi == 0)
        {
+               return FAILED;
+       }
+       
+       *spi = received_spi;
+       return SUCCESS;
+}
+
+/**
+ * Implementation of kernel_interface_t.get_spi.
+ */
+static status_t get_spi(private_kernel_interface_t *this, 
+                                               host_t *src, host_t *dst, 
+                                               protocol_id_t protocol, u_int32_t reqid,
+                                               u_int32_t *spi)
+{
+       DBG2(DBG_KNL, "getting SPI for reqid %d", reqid);
+       
+       if (get_spi_internal(this, src, dst,
+                       (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH,
+                       0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+       {
                DBG1(DBG_KNL, "unable to get SPI for reqid %d", reqid);
                return FAILED;
        }
        
-       DBG2(DBG_KNL, "got SPI 0x%x for reqid %d", received_spi, reqid);
+       DBG2(DBG_KNL, "got SPI 0x%x for reqid %d", *spi, reqid);
+       
+       return SUCCESS;
+}
+
+/**
+ * Implementation of kernel_interface_t.get_cpi.
+ */
+static status_t get_cpi(private_kernel_interface_t *this, 
+                                               host_t *src, host_t *dst, 
+                                               u_int32_t reqid, u_int16_t *cpi)
+{
+       u_int32_t received_spi = 0;
+       DBG2(DBG_KNL, "getting CPI for reqid %d", reqid);
+       
+       if (get_spi_internal(this, src, dst,
+                       IPPROTO_COMP, 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+       {
+               DBG1(DBG_KNL, "unable to get CPI for reqid %d", reqid);
+               return FAILED;
+       }
+       
+       *cpi = htons((u_int16_t)ntohl(received_spi));
+       
+       DBG2(DBG_KNL, "got CPI 0x%x for reqid %d", *cpi, reqid);
        
-       *spi = received_spi;
        return SUCCESS;
 }
 
@@ -1899,7 +1960,8 @@ static status_t add_sa(private_kernel_interface_t *this,
                                           u_int64_t expire_soft, u_int64_t expire_hard,
                                           u_int16_t enc_alg, u_int16_t enc_size,
                                           u_int16_t int_alg, u_int16_t int_size,
-                                          prf_plus_t *prf_plus, mode_t mode, bool encap,
+                                          prf_plus_t *prf_plus, mode_t mode,
+                                          u_int16_t ipcomp, bool encap,
                                           bool replace)
 {
        unsigned char request[BUFFER_SIZE];
@@ -1909,7 +1971,7 @@ static status_t add_sa(private_kernel_interface_t *this,
        
        memset(&request, 0, sizeof(request));
        
-       DBG2(DBG_KNL, "adding SAD entry with SPI 0x%x", spi);
+       DBG2(DBG_KNL, "adding SAD entry with SPI 0x%x and reqid %d", spi, reqid);
 
        hdr = (struct nlmsghdr*)request;
        hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -1920,10 +1982,10 @@ static status_t add_sa(private_kernel_interface_t *this,
        host2xfrm(src, &sa->saddr);
        host2xfrm(dst, &sa->id.daddr);
        sa->id.spi = spi;
-       sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+       sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
        sa->family = src->get_family(src);
        sa->mode = mode;
-       sa->replay_window = 32;
+       sa->replay_window = (protocol == IPPROTO_COMP) ? 0 : 32;
        sa->reqid = reqid;
        /* we currently do not expire SAs by volume/packet count */
        sa->lft.soft_byte_limit = XFRM_INF;
@@ -1994,7 +2056,32 @@ static status_t add_sa(private_kernel_interface_t *this,
                rthdr = XFRM_RTA_NEXT(rthdr);
        }
        
-       /* TODO: add IPComp here */
+       if (ipcomp != IPCOMP_NONE)
+       {
+               rthdr->rta_type = XFRMA_ALG_COMP;
+               alg_name = lookup_algorithm(compression_algs, ipcomp, NULL);
+               if (alg_name == NULL)
+               {
+                       DBG1(DBG_KNL, "algorithm %N not supported by kernel!", 
+                                ipcomp_transform_names, ipcomp);
+                       return FAILED;
+               }
+               DBG2(DBG_KNL, "  using compression algorithm %N",
+                        ipcomp_transform_names, ipcomp);
+               
+               rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo));
+               hdr->nlmsg_len += rthdr->rta_len;
+               if (hdr->nlmsg_len > sizeof(request))
+               {
+                       return FAILED;
+               }
+               
+               struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr);
+               algo->alg_key_len = 0;
+               strcpy(algo->alg_name, alg_name);
+               
+               rthdr = XFRM_RTA_NEXT(rthdr);
+       }
        
        if (encap)
        {
@@ -2062,7 +2149,7 @@ static status_t update_sa(private_kernel_interface_t *this,
        sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
        host2xfrm(dst, &sa_id->daddr);
        sa_id->spi = spi;
-       sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+       sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
        sa_id->family = dst->get_family(dst);
        
        if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
@@ -2190,7 +2277,7 @@ static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
        sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
        host2xfrm(dst, &sa_id->daddr);
        sa_id->spi = spi;
-       sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+       sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
        sa_id->family = dst->get_family(dst);
        
        if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
@@ -2256,7 +2343,7 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
        sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
        host2xfrm(dst, &sa_id->daddr);
        sa_id->spi = spi;
-       sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+       sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
        sa_id->family = dst->get_family(dst);
        
        if (netlink_send_ack(this, this->socket_xfrm, hdr) != SUCCESS)
@@ -2276,7 +2363,8 @@ static status_t add_policy(private_kernel_interface_t *this,
                                                   traffic_selector_t *src_ts,
                                                   traffic_selector_t *dst_ts,
                                                   policy_dir_t direction, protocol_id_t protocol,
-                                                  u_int32_t reqid, bool high_prio, mode_t mode)
+                                                  u_int32_t reqid, bool high_prio, mode_t mode,
+                                                  u_int16_t ipcomp)
 {
        iterator_t *iterator;
        policy_entry_t *current, *policy;
@@ -2301,7 +2389,7 @@ static status_t add_policy(private_kernel_interface_t *this,
                {
                        /* use existing policy */
                        current->refcount++;
-                       DBG2(DBG_KNL, "policy %R===%R already exists, increasing ",
+                       DBG2(DBG_KNL, "policy %R===%R already exists, increasing "
                                 "refcount", src_ts, dst_ts);
                        free(policy);
                        policy = current;
@@ -2348,10 +2436,8 @@ static status_t add_policy(private_kernel_interface_t *this,
        
        struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_info);
        rthdr->rta_type = XFRMA_TMPL;
-
-       rthdr->rta_len = sizeof(struct xfrm_user_tmpl);
-       rthdr->rta_len = RTA_LENGTH(rthdr->rta_len);
-
+       rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
+       
        hdr->nlmsg_len += rthdr->rta_len;
        if (hdr->nlmsg_len > sizeof(request))
        {
@@ -2359,6 +2445,30 @@ static status_t add_policy(private_kernel_interface_t *this,
        }
        
        struct xfrm_user_tmpl *tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rthdr);
+       
+       if (ipcomp != IPCOMP_NONE)
+       {
+               tmpl->reqid = reqid;
+               tmpl->id.proto = IPPROTO_COMP;
+               tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
+               tmpl->mode = mode;
+               tmpl->optional = direction != POLICY_OUT;
+               tmpl->family = src->get_family(src);
+               
+               host2xfrm(src, &tmpl->saddr);
+               host2xfrm(dst, &tmpl->id.daddr);
+               
+               /* add an additional xfrm_user_tmpl */
+               rthdr->rta_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
+               hdr->nlmsg_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
+               if (hdr->nlmsg_len > sizeof(request))
+               {
+                       return FAILED;
+               }
+               
+               tmpl++;
+       }
+       
        tmpl->reqid = reqid;
        tmpl->id.proto = (protocol == PROTO_AH) ? KERNEL_AH : KERNEL_ESP;
        tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
@@ -2588,11 +2698,12 @@ kernel_interface_t *kernel_interface_create()
        
        /* public functions */
        this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
-       this->public.add_sa  = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,u_int16_t,u_int16_t,u_int16_t,prf_plus_t*,mode_t,bool,bool))add_sa;
+       this->public.get_cpi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
+       this->public.add_sa  = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,u_int16_t,u_int16_t,u_int16_t,prf_plus_t*,mode_t,u_int16_t,bool,bool))add_sa;
        this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_t*,host_t*,bool))update_sa;
        this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
        this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
-       this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t))add_policy;
+       this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t,u_int16_t))add_policy;
        this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
        this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy;
        this->public.get_interface = (char*(*)(kernel_interface_t*,host_t*))get_interface_name;
index 5e2bff5..0978b05 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2008 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -78,6 +79,18 @@ struct kernel_interface_t {
                                                protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi);
        
        /**
+        * Get a Compression Parameter Index (CPI) from the kernel.
+        * 
+        * @param src           source address of SA
+        * @param dst           destination address of SA
+        * @param reqid         unique ID for the corresponding SA
+        * @param cpi           allocated cpi
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst, 
+                                               u_int32_t reqid, u_int16_t *cpi);
+       
+       /**
         * Add an SA to the SAD.
         * 
         * add_sa() may update an already allocated
@@ -101,6 +114,7 @@ struct kernel_interface_t {
         * @param int_size              key length of integrity algorithm, if dynamic
         * @param prf_plus              PRF to derive keys from
         * @param mode                  mode of the SA (tunnel, transport)
+        * @param ipcomp                IPComp transform to use
         * @param encap                 enable UDP encapsulation for NAT traversal
         * @param replace               Should an already installed SA be updated?
         * @return                              SUCCESS if operation completed
@@ -111,7 +125,8 @@ struct kernel_interface_t {
                                                u_int64_t expire_soft, u_int64_t expire_hard,
                                            u_int16_t enc_alg, u_int16_t enc_size,
                                            u_int16_t int_alg, u_int16_t int_size,
-                                               prf_plus_t *prf_plus, mode_t mode, bool encap,
+                                               prf_plus_t *prf_plus, mode_t mode,
+                                               u_int16_t ipcomp, bool encap,
                                                bool update);
        
        /**
@@ -177,6 +192,7 @@ struct kernel_interface_t {
         * @param reqid                 uniqe ID of an SA to use to enforce policy
         * @param high_prio             if TRUE, uses a higher priority than any with FALSE
         * @param mode                  mode of SA (tunnel, transport)
+        * @param ipcomp                the IPComp transform used
         * @return                              SUCCESS if operation completed
         */
        status_t (*add_policy) (kernel_interface_t *this,
@@ -184,7 +200,8 @@ struct kernel_interface_t {
                                                        traffic_selector_t *src_ts,
                                                        traffic_selector_t *dst_ts,
                                                        policy_dir_t direction, protocol_id_t protocol,
-                                                       u_int32_t reqid, bool high_prio, mode_t mode);
+                                                       u_int32_t reqid, bool high_prio, mode_t mode,
+                                                       u_int16_t ipcomp);
        
        /**
         * Query the use time of a policy.
index aca8b83..6c04aef 100644 (file)
@@ -22,6 +22,7 @@ CREATE TABLE `child_configs` (
   `mode` tinyint(4) unsigned NOT NULL default '1',
   `dpd_action` tinyint(4) unsigned NOT NULL default '0',
   `close_action` tinyint(4) unsigned NOT NULL default '0',
+  `ipcomp` tinyint(4) unsigned NOT NULL default '0',
   PRIMARY KEY (`id`),
   INDEX (`name`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
index 3777c6e..9b70364 100644 (file)
@@ -125,15 +125,15 @@ static void add_traffic_selectors(private_sql_config_t *this,
  */
 static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
 {
-       int id, lifetime, rekeytime, jitter, hostaccess, mode, dpd, close;
+       int id, lifetime, rekeytime, jitter, hostaccess, mode, dpd, close, ipcomp;
        char *name, *updown;
        child_cfg_t *child_cfg;
        
        if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, 
-                                               &updown, &hostaccess, &mode, &dpd, &close))
+                                               &updown, &hostaccess, &mode, &dpd, &close, &ipcomp))
        {
                child_cfg = child_cfg_create(name, lifetime, rekeytime, jitter,
-                                                                        updown, hostaccess, mode, dpd, close);
+                                                                        updown, hostaccess, mode, dpd, close, ipcomp);
                /* TODO: read proposal from db */
                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
                add_traffic_selectors(this, child_cfg, id);
@@ -152,7 +152,7 @@ static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
        
        e = this->db->query(this->db,
                        "SELECT id, name, lifetime, rekeytime, jitter, "
-                       "updown, hostaccess, mode, dpd_action, close_action "
+                       "updown, hostaccess, mode, dpd_action, close_action, ipcomp "
                        "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
                        "WHERE peer_cfg = ?",
                        DB_INT, id,
index a3f527b..97c304a 100644 (file)
@@ -20,7 +20,8 @@ CREATE TABLE child_configs (
   hostaccess INTEGER NOT NULL DEFAULT '0',
   mode INTEGER NOT NULL DEFAULT '1',
   dpd_action INTEGER NOT NULL DEFAULT '0',
-  close_action INTEGER NOT NULL DEFAULT '0'
+  close_action INTEGER NOT NULL DEFAULT '0',
+  ipcomp INTEGER NOT NULL DEFAULT '0'
 );
 DROP INDEX IF EXISTS child_configs_name;
 CREATE INDEX child_configs_name ON child_configs (
index 54b3bf8..f8b4db0 100644 (file)
@@ -710,7 +710,7 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
                                msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
                                msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100, 
                                msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
-                               msg->add_conn.mode, dpd, ACTION_NONE);
+                               msg->add_conn.mode, dpd, ACTION_NONE, msg->add_conn.ipcomp);
        
        add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
        add_ts(this, &msg->add_conn.other, child_cfg, FALSE);
index 7cd36d6..21f29a3 100644 (file)
@@ -1,6 +1,7 @@
 /*
+ * Copyright (C) 2006-2008 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -70,6 +71,8 @@ struct private_child_sa_t {
                identification_t *id;
                /** actual used SPI, 0 if unused */
                u_int32_t spi;
+               /** Compression Parameter Index (CPI) used, 0 if unused */
+               u_int16_t cpi;
        } me, other;
        
        /**
@@ -148,6 +151,16 @@ struct private_child_sa_t {
        bool encap;
        
        /**
+        * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
+        */
+       ipcomp_transform_t ipcomp;
+       
+       /**
+        * TRUE if we allocated (or tried to allocate) a CPI
+        */
+       bool cpi_allocated;
+       
+       /**
         * mode this SA uses, tunnel/transport
         */
        mode_t mode;
@@ -570,10 +583,21 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
        
        /* send SA down to the kernel */
        DBG2(DBG_CHD, "  SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
+       
+       if (this->ipcomp != IPCOMP_NONE)
+       {
+               /* we install an additional IPComp SA */
+               u_int32_t cpi = htonl(ntohs(mine ? this->me.cpi : this->other.cpi));
+               status = charon->kernel_interface->add_sa(charon->kernel_interface,
+                               src, dst, cpi, IPPROTO_COMP, this->reqid, 0, 0,
+                               ENCR_UNDEFINED, 0, AUTH_UNDEFINED, 0, NULL, mode,
+                               this->ipcomp, FALSE, mine);
+       }
+       
        status = charon->kernel_interface->add_sa(charon->kernel_interface,
                                src, dst, spi, this->protocol, this->reqid, mine ? soft : 0, hard, 
                                this->enc_alg, this->enc_size, this->int_alg, this->int_size,
-                               prf_plus, mode, this->encap, mine);
+                               prf_plus, mode, IPCOMP_NONE, this->encap, mine);
                                        
        this->install_time = time(NULL);
        this->rekey_time = this->install_time + soft;
@@ -677,15 +701,15 @@ static status_t add_policies(private_child_sa_t *this,
                        /* install 3 policies: out, in and forward */
                        status = charon->kernel_interface->add_policy(charon->kernel_interface,
                                        this->me.addr, this->other.addr, my_ts, other_ts, POLICY_OUT,
-                                       this->protocol, this->reqid, high_prio, mode);
+                                       this->protocol, this->reqid, high_prio, mode, this->ipcomp);
                        
                        status |= charon->kernel_interface->add_policy(charon->kernel_interface,
                                        this->other.addr, this->me.addr, other_ts, my_ts, POLICY_IN,
-                                       this->protocol, this->reqid, high_prio, mode);
+                                       this->protocol, this->reqid, high_prio, mode, this->ipcomp);
                        
                        status |= charon->kernel_interface->add_policy(charon->kernel_interface,
                                        this->other.addr, this->me.addr, other_ts, my_ts, POLICY_FWD,
-                                       this->protocol, this->reqid, high_prio, mode);
+                                       this->protocol, this->reqid, high_prio, mode, this->ipcomp);
                        
                        if (status != SUCCESS)
                        {
@@ -786,10 +810,20 @@ static status_t update_hosts(private_child_sa_t *this,
        
        this->encap = encap;
        
-       /* update our (initator) SAs */
+       if (this->ipcomp != IPCOMP_NONE)
+       {
+               /* update our (initator) IPComp SA */
+               charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->me.cpi)),
+                               IPPROTO_COMP, this->other.addr, this->me.addr, other, me, FALSE);
+               /* update his (responder) IPComp SA */
+               charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->other.cpi)), 
+                               IPPROTO_COMP, this->me.addr, this->other.addr, me, other, FALSE);
+       }
+       
+       /* update our (initator) SA */
        charon->kernel_interface->update_sa(charon->kernel_interface, this->me.spi,
                        this->protocol, this->other.addr, this->me.addr, other, me, encap);
-       /* update his (responder) SAs */
+       /* update his (responder) SA */
        charon->kernel_interface->update_sa(charon->kernel_interface, this->other.spi, 
                        this->protocol, this->me.addr, this->other.addr, me, other, encap);
        
@@ -837,13 +871,13 @@ static status_t update_hosts(private_child_sa_t *this,
                        /* reinstall updated policies */
                        charon->kernel_interface->add_policy(charon->kernel_interface,
                                        me, other, policy->my_ts, policy->other_ts, POLICY_OUT,
-                                       this->protocol, this->reqid, TRUE, this->mode);
+                                       this->protocol, this->reqid, TRUE, this->mode, this->ipcomp);
                        charon->kernel_interface->add_policy(charon->kernel_interface, 
                                        other, me, policy->other_ts, policy->my_ts, POLICY_IN,
-                                       this->protocol, this->reqid, TRUE, this->mode);
+                                       this->protocol, this->reqid, TRUE, this->mode, this->ipcomp);
                        charon->kernel_interface->add_policy(charon->kernel_interface,
                                        other, me, policy->other_ts, policy->my_ts, POLICY_FWD,
-                                       this->protocol, this->reqid, TRUE, this->mode);
+                                       this->protocol, this->reqid, TRUE, this->mode, this->ipcomp);
                }
                iterator->destroy(iterator);
        }
@@ -875,6 +909,30 @@ static void set_virtual_ip(private_child_sa_t *this, host_t *ip)
 }
 
 /**
+ * Implementation of child_sa_t.activate_ipcomp.
+ */
+static void activate_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp,
+               u_int16_t other_cpi)
+{
+       this->ipcomp = ipcomp;
+       this->other.cpi = other_cpi;
+}
+
+/**
+ * Implementation of child_sa_t.get_my_cpi.
+ */
+static u_int16_t get_my_cpi(private_child_sa_t *this)
+{
+       if (!this->cpi_allocated)
+       {
+               charon->kernel_interface->get_cpi(charon->kernel_interface,
+                       this->other.addr, this->me.addr, this->reqid, &this->me.cpi);
+               this->cpi_allocated = TRUE;
+       }
+       return this->me.cpi;
+}
+
+/**
  * Implementation of child_sa_t.destroy.
  */
 static void destroy(private_child_sa_t *this)
@@ -907,6 +965,16 @@ static void destroy(private_child_sa_t *this)
                charon->kernel_interface->del_sa(charon->kernel_interface,
                                                                                 this->other.addr, this->other.spi, this->protocol);
        }
+       if (this->me.cpi)
+       {
+               charon->kernel_interface->del_sa(charon->kernel_interface,
+                                                       this->other.addr, htonl(ntohs(this->me.cpi)), IPPROTO_COMP);
+       }
+       if (this->other.cpi)
+       {
+               charon->kernel_interface->del_sa(charon->kernel_interface,
+                                                       this->other.addr, htonl(ntohs(this->other.cpi)), IPPROTO_COMP);
+       }
        
        /* delete all policies in the kernel */
        while (this->policies->remove_last(this->policies, (void**)&policy) == SUCCESS)
@@ -967,6 +1035,8 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
        this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
        this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
        this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
+       this->public.activate_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t,u_int16_t))activate_ipcomp;
+       this->public.get_my_cpi = (u_int16_t(*)(child_sa_t*))get_my_cpi;
        this->public.set_virtual_ip = (void(*)(child_sa_t*,host_t*))set_virtual_ip;
        this->public.destroy = (void(*)(child_sa_t*))destroy;
 
@@ -976,10 +1046,14 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
        this->me.id = my_id->clone(my_id);
        this->other.id = other_id->clone(other_id);
        this->me.spi = 0;
+       this->me.cpi = 0;
        this->other.spi = 0;
+       this->other.cpi = 0;
        this->alloc_ah_spi = 0;
        this->alloc_esp_spi = 0;
        this->encap = encap;
+       this->cpi_allocated = FALSE;
+       this->ipcomp = IPCOMP_NONE;
        this->state = CHILD_CREATED;
        /* reuse old reqid if we are rekeying an existing CHILD_SA */
        this->reqid = rekey ? rekey : ++reqid;
index b8186ef..018f922 100644 (file)
@@ -1,6 +1,7 @@
 /*
+ * Copyright (C) 2006-2008 Tobias Brunner
  * Copyright (C) 2006-2007 Martin Willi
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006 Daniel Roethlisberger
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -254,6 +255,22 @@ struct child_sa_t {
        void (*set_virtual_ip) (child_sa_t *this, host_t *ip);
        
        /**
+        * Activate IPComp by setting the transform ID and CPI values.
+        * 
+        * @param ipcomp        the IPComp transform to use
+        * @param other_cpi     other Compression Parameter Index
+        */
+       void (*activate_ipcomp) (child_sa_t *this, ipcomp_transform_t ipcomp,
+                                               u_int16_t other_cpi);
+       
+       /**
+        * Returns the Compression Parameter Index (CPI) allocated from the kernel.
+        * 
+        * @return                      allocated CPI
+        */
+       u_int16_t (*get_my_cpi) (child_sa_t *this);
+       
+       /**
         * Destroys a child_sa.
         */
        void (*destroy) (child_sa_t *this);
index 1b2ce47..eb5e677 100644 (file)
@@ -1219,7 +1219,7 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
 
        /* install kernel policies */
        child_sa = child_sa_create(this->my_host, this->other_host, this->my_id,
-                                                          this->other_id, child_cfg, FALSE, 0);
+                                                          this->other_id, child_cfg, 0, FALSE);
        me = this->my_host;
        if (this->my_virtual_ip)
        {
index 9dd5add..456eafd 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2008 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -100,6 +101,21 @@ struct private_child_create_t {
        mode_t mode;
        
        /**
+        * IPComp transform to use
+        */
+       ipcomp_transform_t ipcomp;
+       
+       /**
+        * IPComp transform proposed or accepted by the other peer
+        */
+       ipcomp_transform_t ipcomp_received;
+       
+       /**
+        * Other Compression Parameter Index (CPI)
+        */
+       u_int16_t other_cpi;
+       
+       /**
         * reqid to use if we are rekeying
         */
        u_int32_t reqid;
@@ -326,6 +342,12 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
        }
        prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
        
+       if (this->ipcomp != IPCOMP_NONE)
+       {
+               this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp,
+                                                                               this->other_cpi);
+       }
+       
        if (this->initiator)
        {
                status = this->child_sa->update(this->child_sa, this->proposal,
@@ -416,6 +438,36 @@ static void build_payloads(private_child_create_t *this, message_t *message)
 }
 
 /**
+ * Adds an IPCOMP_SUPPORTED notify to the message, if possible
+ */
+static void build_ipcomp_supported_notify(private_child_create_t *this, message_t *message)
+{
+       if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
+       {
+               DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, IPComp is disabled");
+               this->ipcomp = IPCOMP_NONE;
+               return;
+       }
+       
+       u_int16_t cpi = this->child_sa->get_my_cpi(this->child_sa);
+       if (cpi)
+       {
+               chunk_t cpi_chunk, tid_chunk, data;
+               u_int8_t tid = this->ipcomp;
+               cpi_chunk = chunk_from_thing(cpi);
+               tid_chunk = chunk_from_thing(tid);
+               data = chunk_cat("cc", cpi_chunk, tid_chunk);
+               message->add_notify(message, FALSE, IPCOMP_SUPPORTED, data);
+               chunk_free(&data);
+       }
+       else
+       {
+               DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp is disabled");
+               this->ipcomp = IPCOMP_NONE;
+       }
+}
+
+/**
  * Read payloads from message
  */
 static void process_payloads(private_child_create_t *this, message_t *message)
@@ -470,6 +522,25 @@ static void process_payloads(private_child_create_t *this, message_t *message)
                                        case USE_BEET_MODE:
                                                this->mode = MODE_BEET;
                                                break;
+                                       case IPCOMP_SUPPORTED:
+                                       {
+                                               chunk_t data = notify_payload->get_notification_data(notify_payload);
+                                               u_int16_t cpi = *(u_int16_t*)data.ptr;
+                                               ipcomp_transform_t ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
+                                               switch(ipcomp)
+                                               {
+                                                       case IPCOMP_DEFLATE:
+                                                               this->other_cpi = cpi;
+                                                               this->ipcomp_received = ipcomp;
+                                                               break;
+                                                       case IPCOMP_LZS:
+                                                       case IPCOMP_LZJH:
+                                                       default:
+                                                               DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a transform"
+                                                                               " ID we don't support %N", ipcomp_transform_names, ipcomp);
+                                                               break;
+                                               }
+                                       }
                                        default:
                                                break;
                                }
@@ -576,6 +647,12 @@ static status_t build_i(private_child_create_t *this, message_t *message)
                this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
        }
        
+       if (this->config->use_ipcomp(this->config)) {
+               /* IPCOMP_DEFLATE is the only transform we support at the moment */
+               this->ipcomp = IPCOMP_DEFLATE;
+               build_ipcomp_supported_notify(this, message);
+       }
+       
        build_payloads(this, message);
        
        this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
@@ -693,6 +770,16 @@ static status_t build_r(private_child_create_t *this, message_t *message)
                        this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
                        this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
        
+       if (this->config->use_ipcomp(this->config) && this->ipcomp_received != IPCOMP_NONE)
+       {
+               this->ipcomp = this->ipcomp_received;
+               build_ipcomp_supported_notify(this, message);
+       }
+       else if (this->ipcomp_received != IPCOMP_NONE)
+       {
+               DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify but IPComp is disabled, ignoring");
+       }
+       
        switch (select_and_install(this, no_dh))
        {
                case SUCCESS:
@@ -799,6 +886,25 @@ static status_t process_i(private_child_create_t *this, message_t *message)
        
        process_payloads(this, message);
        
+       if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
+       {
+               SIG(CHILD_UP_FAILED, "received an IPCOMP_SUPPORTED notify but we did not "
+                                       "send one previously, no CHILD_SA built");
+               return SUCCESS;
+       }
+       else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
+       {
+               DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
+                               "IPComp is disabled");
+               this->ipcomp = IPCOMP_NONE;
+       }
+       else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
+       {
+               SIG(CHILD_UP_FAILED, "received an IPCOMP_SUPPORTED notify for a transform "
+                                       "we did not propose, no CHILD_SA built");
+               return SUCCESS;
+       }
+       
        if (select_and_install(this, no_dh) == SUCCESS)
        {
                SIG(CHILD_UP_SUCCESS, "CHILD_SA '%s' established successfully",
@@ -877,6 +983,9 @@ static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
        this->dh = NULL;
        this->child_sa = NULL;
        this->mode = MODE_TUNNEL;
+       this->ipcomp = IPCOMP_NONE;
+       this->ipcomp_received = IPCOMP_NONE;
+       this->other_cpi = 0;
        this->reqid = 0;
        this->established = FALSE;
 }
@@ -950,6 +1059,9 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
        this->dh_group = MODP_NONE;
        this->child_sa = NULL;
        this->mode = MODE_TUNNEL;
+       this->ipcomp = IPCOMP_NONE;
+       this->ipcomp_received = IPCOMP_NONE;
+       this->other_cpi = 0;
        this->reqid = 0;
        this->established = FALSE;
        
index 66b007e..4aacbce 100644 (file)
@@ -253,6 +253,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
        }
        msg.add_conn.mobike = conn->policy & POLICY_MOBIKE;
        msg.add_conn.force_encap = conn->policy & POLICY_FORCE_ENCAP;
+       msg.add_conn.ipcomp = conn->policy & POLICY_COMPRESS;
        msg.add_conn.crl_policy = cfg->setup.strictcrlpolicy;
        msg.add_conn.unique = cfg->setup.uniqueids;
        msg.add_conn.algorithms.ike = push_string(&msg, conn->ike);
index 9fa3449..8258fdc 100644 (file)
@@ -198,6 +198,7 @@ struct stroke_msg_t {
                        int mode;
                        int mobike;
                        int force_encap;
+                       int ipcomp;
                        crl_policy_t crl_policy;
                        int unique;
                        struct {