Changeset 4612

Show
Ignore:
Timestamp:
11/11/08 07:37:37 (2 months ago)
Author:
andreas
Message:

preliminary support of Mobile IPv6

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/charon/config/peer_cfg.c

    r4579 r4612  
    2222#include "peer_cfg.h" 
    2323 
     24#include <daemon.h> 
     25 
    2426#include <utils/mutex.h> 
    2527#include <utils/linked_list.h> 
     
    229231 * Check if child_cfg contains traffic selectors 
    230232 */ 
    231 static bool contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts, 
     233static int contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts, 
    232234                        host_t *host) 
    233235{ 
    234236    linked_list_t *selected; 
    235     bool contains = FALSE; 
    236      
     237    int prio; 
     238     
     239    if (child->equal_traffic_selectors(child, mine, ts, host)) 
     240    { 
     241        return 2; 
     242    } 
    237243    selected = child->get_traffic_selectors(child, mine, ts, host); 
    238     contains = selected->get_count(selected)
     244    prio = selected->get_count(selected) ? 1 : 0
    239245    selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy)); 
    240     return contains
     246    return prio
    241247} 
    242248 
     
    251257    child_cfg_t *current, *found = NULL; 
    252258    enumerator_t *enumerator; 
    253      
     259    int best = 0; 
     260 
     261    DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts);     
    254262    enumerator = create_child_cfg_enumerator(this); 
    255263    while (enumerator->enumerate(enumerator, &current)) 
    256264    { 
    257         if (contains_ts(current, TRUE, my_ts, my_host) && 
    258             contains_ts(current, FALSE, other_ts, other_host)) 
     265        int prio = contains_ts(current, TRUE, my_ts, my_host) + 
     266                   contains_ts(current, FALSE, other_ts, other_host); 
     267 
     268        if (prio) 
    259269        { 
    260             found = current->get_ref(current); 
    261             break; 
     270            DBG2(DBG_CFG, "  candidate \"%s\" with prio %d", 
     271                 current->get_name(current), prio); 
     272            if (prio > best) 
     273            { 
     274                best = prio; 
     275                DESTROY_IF(found); 
     276                found = current->get_ref(current); 
     277            } 
    262278        } 
    263279    } 
    264280    enumerator->destroy(enumerator); 
     281    if (found) 
     282    { 
     283        DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d", 
     284             found->get_name(found), best); 
     285    } 
    265286    return found; 
    266287} 
  • trunk/src/charon/plugins/stroke/stroke_config.c

    r4484 r4612  
    776776                msg->add_conn.me.updown, msg->add_conn.me.hostaccess, 
    777777                msg->add_conn.mode, dpd, dpd, msg->add_conn.ipcomp); 
    778      
     778    child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy, 
     779                                            msg->add_conn.install_policy); 
    779780    add_ts(this, &msg->add_conn.me, child_cfg, TRUE); 
    780781    add_ts(this, &msg->add_conn.other, child_cfg, FALSE); 
  • trunk/src/charon/processing/jobs/migrate_job.c

    r4560 r4612  
    8484                                                        this->reqid, TRUE); 
    8585    } 
    86     if (ike_sa == NULL
     86    if (ike_sa
    8787    { 
    88         enumerator_t *enumerator, *children; 
    89         peer_cfg_t *peer_cfg; 
    90         child_cfg_t *found_cfg = NULL; 
    91                  
    92         enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends); 
    93         while (enumerator->enumerate(enumerator, (void**)&peer_cfg)) 
    94         { 
    95             child_cfg_t *child_cfg; 
    96  
    97             if (peer_cfg->get_ike_version(peer_cfg) != 2) 
    98             { 
    99                 continue; 
    100             } 
    101  
    102             children = peer_cfg->create_child_cfg_enumerator(peer_cfg); 
    103             while (children->enumerate(children, &child_cfg)) 
    104             { 
    105                 if (child_cfg->equal_traffic_selectors(child_cfg, TRUE, this->src_ts) && 
    106                     child_cfg->equal_traffic_selectors(child_cfg, FALSE, this->dst_ts)) 
    107                 { 
    108                     found_cfg = child_cfg; 
    109                     break; 
    110                 } 
    111             } 
    112             children->destroy(children); 
    113             if (found_cfg) 
    114             { 
    115                 break; 
    116             } 
    117         } 
    118         enumerator->destroy(enumerator); 
    119  
    120         if (found_cfg == NULL) 
    121         { 
    122             DBG1(DBG_JOB, "no matching child config found for policy %R === %R", 
    123                            this->src_ts, this->dst_ts); 
    124             destroy(this); 
    125             return; 
    126         } 
    127         DBG1(DBG_JOB, "found matching child config '%s' for policy %R === %R", 
    128                        found_cfg->get_name(found_cfg), 
    129                        this->src_ts, this->dst_ts); 
    130  
    131         ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, 
    132                                                             peer_cfg); 
    133         if (ike_sa->get_peer_cfg(ike_sa) == NULL) 
    134         { 
    135             host_t *my_host, *other_host; 
    136             ike_cfg_t *ike_cfg; 
    137  
    138             ike_sa->set_peer_cfg(ike_sa, peer_cfg); 
    139             ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); 
    140             my_host = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg), 0, 0); 
    141             other_host = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg), 0, 0); 
    142             ike_sa->set_my_host(ike_sa, my_host); 
    143             ike_sa->set_other_host(ike_sa, other_host); 
    144         } 
    145         if (this->local) 
    146         { 
    147             ike_sa->set_my_host(ike_sa, this->local->clone(this->local)); 
    148         } 
    149         if (this->remote) 
    150         { 
    151             ike_sa->set_other_host(ike_sa, this->remote->clone(this->remote)); 
    152         } 
    153         /* add a CHILD_SA for 'found_cfg' with a policy that has already been 
    154          * installed in the kernel 
    155          */ 
     88        DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid); 
     89        ike_sa->set_kmaddress(ike_sa, this->local, this->remote); 
     90        charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); 
    15691    } 
    15792    else 
    15893    { 
    159         DBG1(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid); 
    160         if (this->local) 
    161         { 
    162             ike_sa->set_my_host(ike_sa, this->local); 
    163         } 
    164         if (this->remote) 
    165         { 
    166             ike_sa->set_other_host(ike_sa, this->remote->clone(this->remote)); 
    167         } 
     94        DBG1(DBG_JOB, "no CHILD_SA found with reqid {%d}", this->reqid); 
    16895    } 
    169     charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); 
    17096    destroy(this); 
    17197} 
  • trunk/src/charon/sa/child_sa.c

    r4576 r4612  
    156156 
    157157/** 
    158  * Implementation of child_sa_t.get_namy_ 
     158 * Implementation of child_sa_t.get_name 
    159159 */ 
    160160static char *get_name(private_child_sa_t *this) 
     
    335335                last_use = max(last_use, in); 
    336336            } 
    337             if (charon->kernel_interface->query_policy(charon->kernel_interface, 
     337            if (this->mode == MODE_TUNNEL) 
     338            { 
     339                if (charon->kernel_interface->query_policy(charon->kernel_interface, 
    338340                                other_ts, my_ts, POLICY_FWD, &fwd) == SUCCESS) 
    339             { 
    340                 last_use = max(last_use, fwd); 
     341                { 
     342                    last_use = max(last_use, fwd); 
     343                } 
    341344            } 
    342345        } 
     
    596599        this->protocol = proto; 
    597600    } 
    598      
     601 
    599602    /* apply traffic selectors */ 
    600603    enumerator = my_ts_list->create_enumerator(my_ts_list); 
     
    611614    enumerator->destroy(enumerator); 
    612615     
    613     /* enumerate pairs of traffic selectors */ 
    614     enumerator = create_policy_enumerator(this); 
    615     while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) 
    616     { 
    617         /* install 3 policies: out, in and forward */ 
    618         status |= charon->kernel_interface->add_policy(charon->kernel_interface, 
    619                 this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT, 
    620                 this->protocol, this->reqid, high_prio, mode, this->ipcomp); 
     616    if (this->config->install_policy(this->config)) 
     617    { 
     618        /* enumerate pairs of traffic selectors */ 
     619        enumerator = create_policy_enumerator(this); 
     620        while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) 
     621        { 
     622            /* install 3 policies: out, in and forward */ 
     623            status |= charon->kernel_interface->add_policy(charon->kernel_interface, 
     624                    this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT, 
     625                    this->protocol, this->reqid, high_prio, mode, this->ipcomp); 
    621626         
    622         status |= charon->kernel_interface->add_policy(charon->kernel_interface, 
    623                 this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN, 
    624                 this->protocol, this->reqid, high_prio, mode, this->ipcomp); 
     627           status |= charon->kernel_interface->add_policy(charon->kernel_interface, 
     628                   this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN, 
     629                   this->protocol, this->reqid, high_prio, mode, this->ipcomp); 
    625630         
    626         status |= charon->kernel_interface->add_policy(charon->kernel_interface, 
     631            if (mode == MODE_TUNNEL) 
     632            { 
     633                status |= charon->kernel_interface->add_policy(charon->kernel_interface, 
    627634                this->other_addr, this->my_addr, other_ts, my_ts, POLICY_FWD, 
    628635                this->protocol, this->reqid, high_prio, mode, this->ipcomp); 
     636            } 
    629637         
    630         if (status != SUCCESS) 
    631         { 
    632             break; 
    633         } 
    634     } 
    635     enumerator->destroy(enumerator); 
    636      
     638            if (status != SUCCESS) 
     639            { 
     640                break; 
     641            } 
     642        } 
     643        enumerator->destroy(enumerator); 
     644    } 
     645 
    637646    if (status == SUCCESS) 
    638647    { 
     
    695704            this->protocol, this->my_addr, this->other_addr, me, other, encap); 
    696705     
    697     /* update policies */ 
    698     if (!me->ip_equals(me, this->my_addr) || 
    699         !other->ip_equals(other, this->other_addr)) 
    700     { 
    701         enumerator_t *enumerator; 
    702         traffic_selector_t *my_ts, *other_ts; 
     706    if (this->config->install_policy(this->config)) 
     707    { 
     708        /* update policies */ 
     709        if (!me->ip_equals(me, this->my_addr) || 
     710            !other->ip_equals(other, this->other_addr)) 
     711        { 
     712            enumerator_t *enumerator; 
     713            traffic_selector_t *my_ts, *other_ts; 
    703714         
    704         /* always use high priorities, as hosts getting updated are INSTALLED */ 
     715            /* always use high priorities, as hosts getting updated are INSTALLED */ 
     716            enumerator = create_policy_enumerator(this); 
     717            while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) 
     718            { 
     719                /* remove old policies first */ 
     720                charon->kernel_interface->del_policy(charon->kernel_interface, 
     721                                                 my_ts, other_ts, POLICY_OUT); 
     722                charon->kernel_interface->del_policy(charon->kernel_interface, 
     723                                                 other_ts, my_ts,  POLICY_IN); 
     724                if (this->mode == MODE_TUNNEL) 
     725                { 
     726                    charon->kernel_interface->del_policy(charon->kernel_interface, 
     727                                                 other_ts, my_ts, POLICY_FWD); 
     728                } 
     729 
     730                /* check whether we have to update a "dynamic" traffic selector */ 
     731                if (!me->ip_equals(me, this->my_addr) && 
     732                    my_ts->is_host(my_ts, this->my_addr)) 
     733                { 
     734                    my_ts->set_address(my_ts, me); 
     735                } 
     736                if (!other->ip_equals(other, this->other_addr) && 
     737                    other_ts->is_host(other_ts, this->other_addr)) 
     738                { 
     739                    other_ts->set_address(other_ts, other); 
     740                } 
     741             
     742                /* we reinstall the virtual IP to handle interface roaming 
     743                 * correctly */ 
     744                if (vip) 
     745                { 
     746                    charon->kernel_interface->del_ip(charon->kernel_interface, vip); 
     747                    charon->kernel_interface->add_ip(charon->kernel_interface, vip, me); 
     748                } 
     749         
     750                /* reinstall updated policies */ 
     751                charon->kernel_interface->add_policy(charon->kernel_interface, 
     752                        me, other, my_ts, other_ts, POLICY_OUT, this->protocol, 
     753                        this->reqid, TRUE, this->mode, this->ipcomp); 
     754                charon->kernel_interface->add_policy(charon->kernel_interface,  
     755                        other, me, other_ts, my_ts, POLICY_IN, this->protocol, 
     756                        this->reqid, TRUE, this->mode, this->ipcomp); 
     757                if (this->mode == MODE_TUNNEL) 
     758                { 
     759                    charon->kernel_interface->add_policy(charon->kernel_interface, 
     760                        other, me, other_ts, my_ts, POLICY_FWD, this->protocol, 
     761                        this->reqid, TRUE, this->mode, this->ipcomp); 
     762                } 
     763            } 
     764            enumerator->destroy(enumerator); 
     765        } 
     766    } 
     767 
     768    /* apply hosts */ 
     769    if (!this->config->use_proxy_mode(this->config) || this->mode != MODE_TRANSPORT) 
     770    { 
     771        if (!me->equals(me, this->my_addr)) 
     772        { 
     773            this->my_addr->destroy(this->my_addr); 
     774            this->my_addr = me->clone(me); 
     775        } 
     776        if (!other->equals(other, this->other_addr)) 
     777        { 
     778            this->other_addr->destroy(this->other_addr); 
     779            this->other_addr = other->clone(other); 
     780        } 
     781    } 
     782    set_state(this, old); 
     783     
     784    return SUCCESS; 
     785
     786 
     787/** 
     788 * Implementation of child_sa_t.activate_ipcomp. 
     789 */ 
     790static void activate_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp, 
     791        u_int16_t other_cpi) 
     792
     793    this->ipcomp = ipcomp; 
     794    this->other_cpi = other_cpi; 
     795
     796 
     797/** 
     798 * Implementation of child_sa_t.allocate_cpi. 
     799 */ 
     800static u_int16_t allocate_cpi(private_child_sa_t *this) 
     801
     802    if (!this->cpi_allocated) 
     803    { 
     804        charon->kernel_interface->get_cpi(charon->kernel_interface, 
     805            this->other_addr, this->my_addr, this->reqid, &this->my_cpi); 
     806        this->cpi_allocated = TRUE; 
     807    } 
     808    return this->my_cpi; 
     809
     810 
     811/** 
     812 * Implementation of child_sa_t.destroy. 
     813 */ 
     814static void destroy(private_child_sa_t *this) 
     815
     816    enumerator_t *enumerator; 
     817    traffic_selector_t *my_ts, *other_ts; 
     818     
     819    set_state(this, CHILD_DESTROYING); 
     820     
     821    /* delete SAs in the kernel, if they are set up */ 
     822    if (this->my_spi) 
     823    { 
     824        charon->kernel_interface->del_sa(charon->kernel_interface, 
     825                    this->my_addr, this->my_spi, this->protocol); 
     826    } 
     827    if (this->alloc_esp_spi && this->alloc_esp_spi != this->my_spi) 
     828    { 
     829        charon->kernel_interface->del_sa(charon->kernel_interface, 
     830                    this->my_addr, this->alloc_esp_spi, PROTO_ESP); 
     831    } 
     832    if (this->alloc_ah_spi && this->alloc_ah_spi != this->my_spi) 
     833    { 
     834        charon->kernel_interface->del_sa(charon->kernel_interface, 
     835                    this->my_addr, this->alloc_ah_spi, PROTO_AH); 
     836    } 
     837    if (this->other_spi) 
     838    { 
     839        charon->kernel_interface->del_sa(charon->kernel_interface, 
     840                    this->other_addr, this->other_spi, this->protocol); 
     841    } 
     842    if (this->my_cpi) 
     843    { 
     844        charon->kernel_interface->del_sa(charon->kernel_interface, 
     845                    this->my_addr, htonl(ntohs(this->my_cpi)), IPPROTO_COMP); 
     846    } 
     847    if (this->other_cpi) 
     848    { 
     849        charon->kernel_interface->del_sa(charon->kernel_interface, 
     850                    this->other_addr, htonl(ntohs(this->other_cpi)), IPPROTO_COMP); 
     851    } 
     852     
     853    if (this->config->install_policy(this->config)) 
     854    { 
     855        /* delete all policies in the kernel */ 
    705856        enumerator = create_policy_enumerator(this); 
    706857        while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) 
    707858        { 
    708             /* remove old policies first */ 
    709859            charon->kernel_interface->del_policy(charon->kernel_interface, 
    710860                                                 my_ts, other_ts, POLICY_OUT); 
    711861            charon->kernel_interface->del_policy(charon->kernel_interface, 
    712                                                  other_ts, my_ts,  POLICY_IN); 
    713             charon->kernel_interface->del_policy(charon->kernel_interface, 
     862                                                 other_ts, my_ts, POLICY_IN); 
     863            if (this->mode == MODE_TUNNEL) 
     864            { 
     865                charon->kernel_interface->del_policy(charon->kernel_interface, 
    714866                                                 other_ts, my_ts, POLICY_FWD); 
    715          
    716             /* check whether we have to update a "dynamic" traffic selector */ 
    717             if (!me->ip_equals(me, this->my_addr) && 
    718                 my_ts->is_host(my_ts, this->my_addr)) 
    719             { 
    720                 my_ts->set_address(my_ts, me); 
    721             } 
    722             if (!other->ip_equals(other, this->other_addr) && 
    723                 other_ts->is_host(other_ts, this->other_addr)) 
    724             { 
    725                 other_ts->set_address(other_ts, other); 
    726             } 
    727              
    728             /* we reinstall the virtual IP to handle interface roaming 
    729              * correctly */ 
    730             if (vip) 
    731             { 
    732                 charon->kernel_interface->del_ip(charon->kernel_interface, vip); 
    733                 charon->kernel_interface->add_ip(charon->kernel_interface, vip, me); 
    734             } 
    735          
    736             /* reinstall updated policies */ 
    737             charon->kernel_interface->add_policy(charon->kernel_interface, 
    738                         me, other, my_ts, other_ts, POLICY_OUT, this->protocol, 
    739                         this->reqid, TRUE, this->mode, this->ipcomp); 
    740             charon->kernel_interface->add_policy(charon->kernel_interface,  
    741                         other, me, other_ts, my_ts, POLICY_IN, this->protocol, 
    742                         this->reqid, TRUE, this->mode, this->ipcomp); 
    743             charon->kernel_interface->add_policy(charon->kernel_interface, 
    744                         other, me, other_ts, my_ts, POLICY_FWD, this->protocol, 
    745                         this->reqid, TRUE, this->mode, this->ipcomp); 
     867            } 
    746868        } 
    747869        enumerator->destroy(enumerator); 
    748870    } 
    749871 
    750     /* apply hosts */ 
    751     if (!me->equals(me, this->my_addr)) 
    752     { 
    753         this->my_addr->destroy(this->my_addr); 
    754         this->my_addr = me->clone(me); 
    755     } 
    756     if (!other->equals(other, this->other_addr)) 
    757     { 
    758         this->other_addr->destroy(this->other_addr); 
    759         this->other_addr = other->clone(other); 
    760     } 
    761      
    762     set_state(this, old); 
    763      
    764     return SUCCESS; 
    765 } 
    766  
    767 /** 
    768  * Implementation of child_sa_t.activate_ipcomp. 
    769  */ 
    770 static void activate_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp, 
    771         u_int16_t other_cpi) 
    772 { 
    773     this->ipcomp = ipcomp; 
    774     this->other_cpi = other_cpi; 
    775 } 
    776  
    777 /** 
    778  * Implementation of child_sa_t.allocate_cpi. 
    779  */ 
    780 static u_int16_t allocate_cpi(private_child_sa_t *this) 
    781 { 
    782     if (!this->cpi_allocated) 
    783     { 
    784         charon->kernel_interface->get_cpi(charon->kernel_interface, 
    785             this->other_addr, this->my_addr, this->reqid, &this->my_cpi); 
    786         this->cpi_allocated = TRUE; 
    787     } 
    788     return this->my_cpi; 
    789 } 
    790  
    791 /** 
    792  * Implementation of child_sa_t.destroy. 
    793  */ 
    794 static void destroy(private_child_sa_t *this) 
    795 { 
    796     enumerator_t *enumerator; 
    797     traffic_selector_t *my_ts, *other_ts; 
    798      
    799     set_state(this, CHILD_DESTROYING); 
    800      
    801     /* delete SAs in the kernel, if they are set up */ 
    802     if (this->my_spi) 
    803     { 
    804         charon->kernel_interface->del_sa(charon->kernel_interface, 
    805                     this->my_addr, this->my_spi, this->protocol); 
    806     } 
    807     if (this->alloc_esp_spi && this->alloc_esp_spi != this->my_spi) 
    808     { 
    809         charon->kernel_interface->del_sa(charon->kernel_interface, 
    810                     this->my_addr, this->alloc_esp_spi, PROTO_ESP); 
    811     } 
    812     if (this->alloc_ah_spi && this->alloc_ah_spi != this->my_spi) 
    813     { 
    814         charon->kernel_interface->del_sa(charon->kernel_interface, 
    815                     this->my_addr, this->alloc_ah_spi, PROTO_AH); 
    816     } 
    817     if (this->other_spi) 
    818     { 
    819         charon->kernel_interface->del_sa(charon->kernel_interface, 
    820                     this->other_addr, this->other_spi, this->protocol); 
    821     } 
    822     if (this->my_cpi) 
    823     { 
    824         charon->kernel_interface->del_sa(charon->kernel_interface, 
    825                     this->my_addr, htonl(ntohs(this->my_cpi)), IPPROTO_COMP); 
    826     } 
    827     if (this->other_cpi) 
    828     { 
    829         charon->kernel_interface->del_sa(charon->kernel_interface, 
    830                     this->other_addr, htonl(ntohs(this->other_cpi)), IPPROTO_COMP); 
    831     } 
    832      
    833     /* delete all policies in the kernel */ 
    834     enumerator = create_policy_enumerator(this); 
    835     while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) 
    836     { 
    837         charon->kernel_interface->del_policy(charon->kernel_interface, 
    838                                              my_ts, other_ts, POLICY_OUT); 
    839         charon->kernel_interface->del_policy(charon->kernel_interface, 
    840                                              other_ts, my_ts, POLICY_IN); 
    841         charon->kernel_interface->del_policy(charon->kernel_interface, 
    842                                              other_ts, my_ts, POLICY_FWD); 
    843     } 
    844     enumerator->destroy(enumerator); 
    845      
    846872    this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy)); 
    847873    this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy)); 
     
    910936    this->config = config; 
    911937    config->get_ref(config); 
     938 
     939    /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */   
     940    if (config->get_mode(config) == MODE_TRANSPORT && 
     941        config->use_proxy_mode(config)) 
     942    { 
     943        ts_type_t type; 
     944        int family; 
     945        chunk_t addr; 
     946        host_t *host; 
     947        enumerator_t *enumerator; 
     948        linked_list_t *my_ts_list, *other_ts_list; 
     949        traffic_selector_t *my_ts, *other_ts; 
     950 
     951        this->mode = MODE_TRANSPORT; 
     952 
     953        my_ts_list = config->get_traffic_selectors(config, TRUE, NULL, me); 
     954        enumerator = my_ts_list->create_enumerator(my_ts_list); 
     955        if (enumerator->enumerate(enumerator, &my_ts)) 
     956        { 
     957            if (my_ts->is_host(my_ts, NULL) && 
     958               !my_ts->is_host(my_ts, this->my_addr)) 
     959            { 
     960                type = my_ts->get_type(my_ts); 
     961                family = (type == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6; 
     962                addr = my_ts->get_from_address(my_ts); 
     963                host = host_create_from_chunk(family, addr, 0); 
     964                free(addr.ptr); 
     965                DBG1(DBG_CHD, "my address: %H is a transport mode proxy for %H", 
     966                               this->my_addr, host);  
     967                this->my_addr->destroy(this->my_addr); 
     968                this->my_addr = host; 
     969            } 
     970        } 
     971        enumerator->destroy(enumerator); 
     972        my_ts_list->destroy_offset(my_ts_list, offsetof(traffic_selector_t, destroy)); 
     973 
     974        other_ts_list = config->get_traffic_selectors(config, FALSE, NULL, other); 
     975        enumerator = other_ts_list->create_enumerator(other_ts_list); 
     976        if (enumerator->enumerate(enumerator, &other_ts)) 
     977        { 
     978            if (other_ts->is_host(other_ts, NULL) && 
     979               !other_ts->is_host(other_ts, this->other_addr)) 
     980            { 
     981                type = other_ts->get_type(other_ts); 
     982                family = (type == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6; 
     983                addr = other_ts->get_from_address(other_ts); 
     984                host = host_create_from_chunk(family, addr, 0); 
     985                free(addr.ptr); 
     986                DBG1(DBG_CHD, "other address: %H is a transport mode proxy for %H", 
     987                               this->other_addr, host);  
     988                this->other_addr->destroy(this->other_addr); 
     989                this->other_addr = host; 
     990            } 
     991        } 
     992        enumerator->destroy(enumerator); 
     993        other_ts_list->destroy_offset(other_ts_list, offsetof(traffic_selector_t, destroy)); 
     994    } 
    912995     
    913996    return &this->public; 
  • trunk/src/charon/sa/child_sa.h

    r4525 r4612  
    324324 * Constructor to create a new child_sa_t. 
    325325 * 
    326  * @param me            own address 
    327  * @param other         remote address 
    328  * @param my_id         id of own peer 
    329  * @param other_id      id of remote peer 
    330  * @param config        config to use for this CHILD_SA 
    331  * @param reqid         reqid of old CHILD_SA when rekeying, 0 otherwise 
    332  * @param encap         TRUE to enable UDP encapsulation (NAT traversal) 
    333  * @return              child_sa_t object 
     326 * @param me                own address 
     327 * @param other             remote address 
     328 * @param my_id             id of own peer 
     329 * @param other_id          id of remote peer 
     330 * @param config            config to use for this CHILD_SA 
     331 * @param reqid             reqid of old CHILD_SA when rekeying, 0 otherwise 
     332 * @param encap             TRUE to enable UDP encapsulation (NAT traversal) 
     333 * @param proxy             TRUE if IPsec transport SA is to be set up in proxy mode 
     334 * @param install_policy    TRUE if kernel policies are to be installed 
     335 * @return                  child_sa_t object 
    334336 */ 
    335337child_sa_t * child_sa_create(host_t *me, host_t *other, child_cfg_t *config, 
  • trunk/src/charon/sa/ike_sa.c

    r4576 r4612  
    251251     */ 
    252252    bool ike_initiator; 
     253 
     254    /** 
     255     * local host address to be used for IKE, set via MIGRATE kernel message 
     256     */ 
     257    host_t *local_host; 
     258 
     259    /** 
     260     * remote host address to be used for IKE, set via MIGRATE kernel message 
     261     */ 
     262    host_t *remote_host; 
    253263}; 
    254264 
     
    944954} 
    945955 
     956/** 
     957 * Implementation of ike_sa_t.set_kmaddress. 
     958 */ 
     959static void set_kmaddress(private_ike_sa_t *this, host_t *local, host_t *remote) 
     960{ 
     961    DESTROY_IF(this->local_host); 
     962    DESTROY_IF(this->remote_host); 
     963    this->local_host = local->clone(local); 
     964    this->remote_host = remote->clone(remote); 
     965} 
     966 
    946967#ifdef ME 
    947968/** 
     
    10481069    host_t *host; 
    10491070     
    1050     host = host_create_from_dns(this->ike_cfg->get_other_addr(this->ike_cfg), 
    1051                                 0, IKEV2_UDP_PORT); 
     1071    if (this->remote_host) 
     1072    { 
     1073        host = this->remote_host->clone(this->remote_host); 
     1074        host->set_port(host, IKEV2_UDP_PORT); 
     1075    } 
     1076    else 
     1077    { 
     1078        host = host_create_from_dns(this->ike_cfg->get_other_addr(this->ike_cfg), 
     1079                                    0, IKEV2_UDP_PORT); 
     1080    } 
    10521081    if (host) 
    10531082    { 
     
    10551084    } 
    10561085     
    1057     host = host_create_from_dns(this->ike_cfg->get_my_addr(this->ike_cfg), 
    1058                                 this->my_host->get_family(this->my_host), 
    1059                                 IKEV2_UDP_PORT); 
    1060      
    1061     if (host && host->is_anyaddr(host) && 
    1062         !this->other_host->is_anyaddr(this->other_host)) 
    1063     { 
    1064         host->destroy(host); 
    1065         host = charon->kernel_interface->get_source_addr( 
     1086    if (this->local_host) 
     1087    { 
     1088        host = this->local_host->clone(this->local_host); 
     1089        host->set_port(host, IKEV2_UDP_PORT); 
     1090    } 
     1091    else 
     1092    { 
     1093        host = host_create_from_dns(this->ike_cfg->get_my_addr(this->ike_cfg), 
     1094                                    this->my_host->get_family(this->my_host), 
     1095                                    IKEV2_UDP_PORT); 
     1096     
     1097        if (host && host->is_anyaddr(host) && 
     1098            !this->other_host->is_anyaddr(this->other_host)) 
     1099        { 
     1100            host->destroy(host); 
     1101            host = charon->kernel_interface->get_source_addr( 
    10661102                            charon->kernel_interface, this->other_host, NULL); 
    1067         if (host) 
    1068         { 
    1069             host->set_port(host, IKEV2_UDP_PORT); 
     1103            if (host) 
     1104            { 
     1105                host->set_port(host, IKEV2_UDP_PORT); 
     1106            } 
    10701107        } 
    10711108    } 
     
    12651302    my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me); 
    12661303    other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other); 
     1304 
    12671305    status = child_sa->add_policies(child_sa, my_ts, other_ts, 
    1268                                     child_cfg->get_mode(child_cfg), PROTO_NONE); 
     1306                            child_cfg->get_mode(child_cfg), PROTO_NONE); 
     1307 
    12691308    my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); 
    12701309    other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); 
     
    13191358    return SUCCESS; 
    13201359} 
     1360 
    13211361/** 
    13221362 * Implementation of ike_sa_t.process_message. 
     
    13901430        me = message->get_destination(message); 
    13911431        other = message->get_source(message); 
    1392      
     1432 
    13931433        /* if this IKE_SA is virgin, we check for a config */ 
    13941434        if (this->ike_cfg == NULL) 
     
    22362276    DESTROY_IF(this->my_id); 
    22372277    DESTROY_IF(this->other_id); 
     2278    DESTROY_IF(this->local_host); 
     2279    DESTROY_IF(this->remote_host); 
    22382280    DESTROY_IF(this->eap_identity); 
    22392281     
     
    23202362    this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip; 
    23212363    this->public.add_dns_server = (void (*)(ike_sa_t*,host_t*))add_dns_server; 
     2364    this->public.set_kmaddress = (void (*)(ike_sa_t*,host_t*,host_t*))set_kmaddress; 
    23222365#ifdef ME 
    23232366    this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server; 
     
    23352378    this->ike_sa_id = ike_sa_id->clone(ike_sa_id); 
    23362379    this->child_sas = linked_list_create(); 
    2337     this->my_host = host_create_from_string("%any", IKEV2_UDP_PORT); 
    2338     this->other_host = host_create_from_string("%any", IKEV2_UDP_PORT); 
     2380    this->my_host = host_create_any(AF_INET); 
     2381    this->other_host = host_create_any(AF_INET); 
    23392382    this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty); 
    23402383    this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty); 
     
    23632406    this->keyingtry = 0; 
    23642407    this->ike_initiator = FALSE; 
     2408    this->local_host = NULL; 
     2409    this->remote_host = NULL; 
    23652410#ifdef ME 
    23662411    this->is_mediation_server = FALSE; 
  • trunk/src/charon/sa/ike_sa.h

    r4531 r4612  
    866866     
    867867    /** 
     868     * Set local and remote host addresses to be used for IKE. 
     869     * 
     870     * These addresses are communicated via the KMADDRESS field of a MIGRATE 
     871     * message sent via the NETLINK or PF _KEY kernel socket interface. 
     872     * 
     873     * @param local         local kmaddress 
     874     * @param remote        remote kmaddress 
     875     */ 
     876    void (*set_kmaddress) (ike_sa_t *this, host_t *local, host_t *remote); 
     877 
     878    /** 
    868879     * Inherit all attributes of other to this after rekeying. 
    869880     * 
  • trunk/src/charon/sa/tasks/child_create.c

    r4572 r4612  
    301301        { 
    302302            case MODE_TRANSPORT: 
    303                 if (!ts_list_is_host(this->tsi, other) || 
    304                     !ts_list_is_host(this->tsr, me)) 
     303                if (!this->config->use_proxy_mode(this->config) && 
     304                       (!ts_list_is_host(this->tsi, other) || 
     305                        !ts_list_is_host(this->tsr, me)) 
     306                   ) 
    305307                { 
    306308                    this->mode = MODE_TUNNEL; 
  • trunk/src/pluto/constants.c

    r3839 r4612  
    518518    "BEET", 
    519519    "MOBIKE", 
     520    "ECDSA", 
     521    "PROXY", 
    520522    NULL 
    521523    }; 
  • trunk/src/pluto/constants.h

    r4482 r4612  
    878878#define POLICY_MOBIKE       LELEM(23)   /* enable MOBIKE for IKEv2  */ 
    879879#define POLICY_FORCE_ENCAP  LELEM(24)   /* force UDP encapsulation (IKEv2)  */ 
    880 #define POLICY_ECDSASIG LELEM(25)   /* ecdsa signature (IKEv2) */ 
     880#define POLICY_ECDSASIG     LELEM(25)   /* ECDSA signature (IKEv2) */ 
     881#define POLICY_PROXY        LELEM(26)   /* proxy transport mode (MIPv6) */ 
    881882 
    882883/* Any IPsec policy?  If not, a connection description 
  • trunk/src/starter/args.c

    r4276 r4612  
    200200    { ARG_MISC, 0, NULL  /* KW_PFS */                                              }, 
    201201    { ARG_MISC, 0, NULL  /* KW_COMPRESS */                                         }, 
     202    { ARG_ENUM, offsetof(starter_conn_t, install_policy), LST_bool                 }, 
    202203    { ARG_MISC, 0, NULL  /* KW_AUTH */                                             }, 
    203204    { ARG_MISC, 0, NULL  /* KW_AUTHBY */                                           }, 
  • trunk/src/starter/confread.c

    r4269 r4612  
    8080    cfg->conn_default.addr_family           = AF_INET; 
    8181    cfg->conn_default.tunnel_addr_family    = AF_INET; 
     82    cfg->conn_default.install_policy    = TRUE; 
    8283    cfg->conn_default.dpd_delay     =  30; /* seconds */ 
    8384    cfg->conn_default.dpd_timeout       = 150; /* seconds */ 
     
    498499            conn->policy &= ~(POLICY_TUNNEL | POLICY_SHUNT_MASK); 
    499500            if (streq(kw->value, "tunnel")) 
     501            { 
    500502                conn->policy |= POLICY_TUNNEL; 
     503            } 
    501504            else if (streq(kw->value, "beet")) 
     505            { 
    502506                conn->policy |= POLICY_BEET; 
     507            } 
     508            else if (streq(kw->value, "transport_proxy")) 
     509            { 
     510                conn->policy |= POLICY_PROXY;            
     511            }    
    503512            else if (s