~ubuntu-branches/ubuntu/precise/strongswan/precise

« back to all changes in this revision

Viewing changes to src/libcharon/plugins/ha/ha_dispatcher.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2010-10-18 10:19:52 UTC
  • mfrom: (6.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20101018101952-zqd04yd4jvls81mj
Tags: 4.4.1-5ubuntu1
* Merge from debian unstable. Remaining change
  - Build depend on libnm-glib-dev instead of libnm-glib-vpn-dev to
    match the network manager package naming in Ubuntu

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
        ha_segments_t *segments;
42
42
 
43
43
        /**
 
44
         * Cache for resync
 
45
         */
 
46
        ha_cache_t *cache;
 
47
 
 
48
        /**
 
49
         * Kernel helper
 
50
         */
 
51
        ha_kernel_t *kernel;
 
52
 
 
53
        /**
 
54
         * HA enabled pool
 
55
         */
 
56
        ha_attribute_t *attr;
 
57
 
 
58
        /**
44
59
         * Dispatcher job
45
60
         */
46
61
        callback_job_t *job;
153
168
                                old_sa = NULL;
154
169
                        }
155
170
                        ike_sa->set_state(ike_sa, IKE_CONNECTING);
 
171
                        this->cache->cache(this->cache, ike_sa, message);
 
172
                        message = NULL;
156
173
                        charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
157
174
                }
158
175
                else
167
184
        {
168
185
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, old_sa);
169
186
        }
 
187
        DESTROY_IF(message);
170
188
}
171
189
 
172
190
/**
201
219
        enumerator_t *enumerator;
202
220
        ike_sa_t *ike_sa = NULL;
203
221
        peer_cfg_t *peer_cfg = NULL;
 
222
        auth_cfg_t *auth;
 
223
        bool received_vip = FALSE;
204
224
 
205
225
        enumerator = message->create_attribute_enumerator(message);
206
226
        while (enumerator->enumerate(enumerator, &attribute, &value))
222
242
                        case HA_REMOTE_ID:
223
243
                                ike_sa->set_other_id(ike_sa, value.id->clone(value.id));
224
244
                                break;
 
245
                        case HA_REMOTE_EAP_ID:
 
246
                                auth = auth_cfg_create();
 
247
                                auth->add(auth, AUTH_RULE_EAP_IDENTITY, value.id->clone(value.id));
 
248
                                ike_sa->add_auth_cfg(ike_sa, FALSE, auth);
 
249
                                break;
225
250
                        case HA_LOCAL_ADDR:
226
251
                                ike_sa->set_my_host(ike_sa, value.host->clone(value.host));
227
252
                                break;
233
258
                                break;
234
259
                        case HA_REMOTE_VIP:
235
260
                                ike_sa->set_virtual_ip(ike_sa, FALSE, value.host);
 
261
                                received_vip = TRUE;
236
262
                                break;
237
263
                        case HA_ADDITIONAL_ADDR:
238
264
                                ike_sa->add_additional_address(ike_sa,
265
291
                                set_condition(ike_sa, value.u32, COND_CERTREQ_SEEN);
266
292
                                set_condition(ike_sa, value.u32, COND_ORIGINAL_INITIATOR);
267
293
                                break;
268
 
                        case HA_INITIATE_MID:
269
 
                                ike_sa->set_message_id(ike_sa, TRUE, value.u32);
270
 
                                break;
271
 
                        case HA_RESPOND_MID:
272
 
                                ike_sa->set_message_id(ike_sa, FALSE, value.u32);
273
 
                                break;
274
294
                        default:
275
295
                                break;
276
296
                }
282
302
                if (ike_sa->get_state(ike_sa) == IKE_CONNECTING &&
283
303
                        ike_sa->get_peer_cfg(ike_sa))
284
304
                {
 
305
                        DBG1(DBG_CFG, "installed HA passive IKE_SA '%s' %H[%Y]...%H[%Y]",
 
306
                                 ike_sa->get_name(ike_sa),
 
307
                                 ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
 
308
                                 ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
285
309
                        ike_sa->set_state(ike_sa, IKE_PASSIVE);
286
310
                }
287
 
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 
311
                if (received_vip)
 
312
                {
 
313
                        host_t *vip;
 
314
                        char *pool;
 
315
 
 
316
                        peer_cfg = ike_sa->get_peer_cfg(ike_sa);
 
317
                        vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
 
318
                        if (peer_cfg && vip)
 
319
                        {
 
320
                                pool = peer_cfg->get_pool(peer_cfg);
 
321
                                if (pool)
 
322
                                {
 
323
                                        this->attr->reserve(this->attr, pool, vip);
 
324
                                }
 
325
                        }
 
326
                }
 
327
                this->cache->cache(this->cache, ike_sa, message);
 
328
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 
329
        }
 
330
        else
 
331
        {
 
332
                DBG1(DBG_CFG, "passive HA IKE_SA to update not found");
 
333
                message->destroy(message);
 
334
        }
 
335
}
 
336
 
 
337
/**
 
338
 * Process messages of type IKE_MID_INITIATOR/RESPONDER
 
339
 */
 
340
static void process_ike_mid(private_ha_dispatcher_t *this,
 
341
                                                           ha_message_t *message, bool initiator)
 
342
{
 
343
        ha_message_attribute_t attribute;
 
344
        ha_message_value_t value;
 
345
        enumerator_t *enumerator;
 
346
        ike_sa_t *ike_sa = NULL;
 
347
        u_int32_t mid = 0;
 
348
 
 
349
        enumerator = message->create_attribute_enumerator(message);
 
350
        while (enumerator->enumerate(enumerator, &attribute, &value))
 
351
        {
 
352
                switch (attribute)
 
353
                {
 
354
                        case HA_IKE_ID:
 
355
                                ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
 
356
                                                                                                                  value.ike_sa_id);
 
357
                                break;
 
358
                        case HA_MID:
 
359
                                mid = value.u32;
 
360
                                break;
 
361
                        default:
 
362
                                break;
 
363
                }
 
364
        }
 
365
        enumerator->destroy(enumerator);
 
366
 
 
367
        if (ike_sa)
 
368
        {
 
369
                if (mid)
 
370
                {
 
371
                        ike_sa->set_message_id(ike_sa, initiator, mid);
 
372
                }
 
373
                this->cache->cache(this->cache, ike_sa, message);
 
374
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 
375
        }
 
376
        else
 
377
        {
 
378
                message->destroy(message);
288
379
        }
289
380
}
290
381
 
297
388
        ha_message_attribute_t attribute;
298
389
        ha_message_value_t value;
299
390
        enumerator_t *enumerator;
300
 
        ike_sa_t *ike_sa;
 
391
        ike_sa_t *ike_sa = NULL;
301
392
 
302
393
        enumerator = message->create_attribute_enumerator(message);
303
394
        while (enumerator->enumerate(enumerator, &attribute, &value))
307
398
                        case HA_IKE_ID:
308
399
                                ike_sa = charon->ike_sa_manager->checkout(
309
400
                                                                        charon->ike_sa_manager, value.ike_sa_id);
310
 
                                if (ike_sa)
311
 
                                {
312
 
                                        charon->ike_sa_manager->checkin_and_destroy(
313
 
                                                                        charon->ike_sa_manager, ike_sa);
314
 
                                }
315
401
                                break;
316
402
                        default:
317
403
                                break;
318
404
                }
319
405
        }
320
406
        enumerator->destroy(enumerator);
 
407
        if (ike_sa)
 
408
        {
 
409
                this->cache->cache(this->cache, ike_sa, message);
 
410
                charon->ike_sa_manager->checkin_and_destroy(
 
411
                                                charon->ike_sa_manager, ike_sa);
 
412
        }
 
413
        else
 
414
        {
 
415
                message->destroy(message);
 
416
        }
321
417
}
322
418
 
323
419
/**
366
462
        u_int16_t inbound_cpi = 0, outbound_cpi = 0;
367
463
        u_int8_t mode = MODE_TUNNEL, ipcomp = 0;
368
464
        u_int16_t encr = ENCR_UNDEFINED, integ = AUTH_UNDEFINED, len = 0;
 
465
        u_int seg_i, seg_o;
369
466
        chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty;
370
467
        chunk_t encr_i, integ_i, encr_r, integ_r;
371
468
        linked_list_t *local_ts, *remote_ts;
381
478
                        case HA_IKE_ID:
382
479
                                ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
383
480
                                                                                                                  value.ike_sa_id);
384
 
                                initiator = value.ike_sa_id->is_initiator(value.ike_sa_id);
385
481
                                break;
386
482
                        case HA_CONFIG_NAME:
387
483
                                config_name = value.str;
388
484
                                break;
 
485
                        case HA_INITIATOR:
 
486
                                initiator = value.u8;
 
487
                                break;
389
488
                        case HA_INBOUND_SPI:
390
489
                                inbound_spi = value.u32;
391
490
                                break;
431
530
        if (!ike_sa)
432
531
        {
433
532
                DBG1(DBG_CHD, "IKE_SA for HA CHILD_SA not found");
 
533
                message->destroy(message);
434
534
                return;
435
535
        }
436
536
        config = find_child_cfg(ike_sa, config_name);
438
538
        {
439
539
                DBG1(DBG_CHD, "HA is missing nodes child configuration");
440
540
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 
541
                message->destroy(message);
441
542
                return;
442
543
        }
443
544
 
524
625
                local_ts->destroy_offset(local_ts, offsetof(traffic_selector_t, destroy));
525
626
                remote_ts->destroy_offset(remote_ts, offsetof(traffic_selector_t, destroy));
526
627
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 
628
                message->destroy(message);
527
629
                return;
528
630
        }
529
631
 
 
632
        seg_i = this->kernel->get_segment_spi(this->kernel,
 
633
                                                                ike_sa->get_my_host(ike_sa), inbound_spi);
 
634
        seg_o = this->kernel->get_segment_spi(this->kernel,
 
635
                                                                ike_sa->get_other_host(ike_sa), outbound_spi);
 
636
 
 
637
        DBG1(DBG_CFG, "installed HA CHILD_SA %s{%d} %#R=== %#R "
 
638
                "(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
 
639
                child_sa->get_reqid(child_sa), local_ts, remote_ts,
 
640
                seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
 
641
                seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : "");
530
642
        child_sa->add_policies(child_sa, local_ts, remote_ts);
531
643
        local_ts->destroy_offset(local_ts, offsetof(traffic_selector_t, destroy));
532
644
        remote_ts->destroy_offset(remote_ts, offsetof(traffic_selector_t, destroy));
533
645
 
534
646
        child_sa->set_state(child_sa, CHILD_INSTALLED);
535
647
        ike_sa->add_child_sa(ike_sa, child_sa);
 
648
        message->destroy(message);
536
649
        charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
537
650
}
538
651
 
546
659
        ha_message_value_t value;
547
660
        enumerator_t *enumerator;
548
661
        ike_sa_t *ike_sa = NULL;
 
662
        child_sa_t *child_sa;
 
663
        u_int32_t spi = 0;
549
664
 
550
665
        enumerator = message->create_attribute_enumerator(message);
551
666
        while (enumerator->enumerate(enumerator, &attribute, &value))
557
672
                                                                                                                  value.ike_sa_id);
558
673
                                break;
559
674
                        case HA_INBOUND_SPI:
560
 
                                if (ike_sa)
561
 
                                {
562
 
                                        ike_sa->destroy_child_sa(ike_sa, PROTO_ESP, value.u32);
563
 
                                }
 
675
                                spi = value.u32;
564
676
                                break;
565
677
                        default:
566
678
                                break;
567
679
                }
568
680
        }
 
681
        enumerator->destroy(enumerator);
 
682
 
569
683
        if (ike_sa)
570
684
        {
 
685
                child_sa = ike_sa->get_child_sa(ike_sa, PROTO_ESP, spi, TRUE);
 
686
                if (child_sa)
 
687
                {
 
688
                        ike_sa->destroy_child_sa(ike_sa, PROTO_ESP, spi);
 
689
                }
571
690
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
572
691
        }
573
 
        enumerator->destroy(enumerator);
 
692
        message->destroy(message);
574
693
}
575
694
 
576
695
/**
605
724
                }
606
725
        }
607
726
        enumerator->destroy(enumerator);
 
727
        message->destroy(message);
608
728
}
609
729
 
610
730
/**
633
753
        enumerator->destroy(enumerator);
634
754
 
635
755
        this->segments->handle_status(this->segments, mask);
 
756
        message->destroy(message);
636
757
}
637
758
 
638
759
/**
651
772
                switch (attribute)
652
773
                {
653
774
                        case HA_SEGMENT:
654
 
                                this->segments->resync(this->segments, value.u16);
 
775
                                this->cache->resync(this->cache, value.u16);
655
776
                                break;
656
777
                        default:
657
778
                                break;
658
779
                }
659
780
        }
660
781
        enumerator->destroy(enumerator);
 
782
        message->destroy(message);
661
783
}
662
784
 
663
785
/**
666
788
static job_requeue_t dispatch(private_ha_dispatcher_t *this)
667
789
{
668
790
        ha_message_t *message;
 
791
        ha_message_type_t type;
669
792
 
670
793
        message = this->socket->pull(this->socket);
671
 
        switch (message->get_type(message))
 
794
        type = message->get_type(message);
 
795
        if (type != HA_STATUS)
 
796
        {
 
797
                DBG2(DBG_CFG, "received HA %N message", ha_message_type_names,
 
798
                         message->get_type(message));
 
799
        }
 
800
        switch (type)
672
801
        {
673
802
                case HA_IKE_ADD:
674
803
                        process_ike_add(this, message);
676
805
                case HA_IKE_UPDATE:
677
806
                        process_ike_update(this, message);
678
807
                        break;
 
808
                case HA_IKE_MID_INITIATOR:
 
809
                        process_ike_mid(this, message, TRUE);
 
810
                        break;
 
811
                case HA_IKE_MID_RESPONDER:
 
812
                        process_ike_mid(this, message, FALSE);
 
813
                        break;
679
814
                case HA_IKE_DELETE:
680
815
                        process_ike_delete(this, message);
681
816
                        break;
698
833
                        process_resync(this, message);
699
834
                        break;
700
835
                default:
701
 
                        DBG1(DBG_CFG, "received unknown HA message type %d",
702
 
                                 message->get_type(message));
 
836
                        DBG1(DBG_CFG, "received unknown HA message type %d", type);
 
837
                        message->destroy(message);
703
838
                        break;
704
839
        }
705
 
        message->destroy(message);
706
 
 
707
840
        return JOB_REQUEUE_DIRECT;
708
841
}
709
842
 
710
 
/**
711
 
 * Implementation of ha_dispatcher_t.destroy.
712
 
 */
713
 
static void destroy(private_ha_dispatcher_t *this)
 
843
METHOD(ha_dispatcher_t, destroy, void,
 
844
        private_ha_dispatcher_t *this)
714
845
{
715
846
        this->job->cancel(this->job);
716
847
        free(this);
720
851
 * See header
721
852
 */
722
853
ha_dispatcher_t *ha_dispatcher_create(ha_socket_t *socket,
723
 
                                                                          ha_segments_t *segments)
 
854
                                                                        ha_segments_t *segments, ha_cache_t *cache,
 
855
                                                                        ha_kernel_t *kernel, ha_attribute_t *attr)
724
856
{
725
 
        private_ha_dispatcher_t *this = malloc_thing(private_ha_dispatcher_t);
726
 
 
727
 
        this->public.destroy = (void(*)(ha_dispatcher_t*))destroy;
728
 
 
729
 
        this->socket = socket;
730
 
        this->segments = segments;
 
857
        private_ha_dispatcher_t *this;
 
858
 
 
859
 
 
860
        INIT(this,
 
861
                .public = {
 
862
                        .destroy = _destroy,
 
863
                },
 
864
                .socket = socket,
 
865
                .segments = segments,
 
866
                .cache = cache,
 
867
                .kernel = kernel,
 
868
                .attr = attr,
 
869
        );
731
870
        this->job = callback_job_create((callback_job_cb_t)dispatch,
732
871
                                                                        this, NULL, NULL);
733
872
        charon->processor->queue_job(charon->processor, (job_t*)this->job);