Coverage Report

Created: 2026-09-01 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/strongswan/src/libcharon/processing/jobs/migrate_job.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2008 Andreas Steffen
3
 *
4
 * Copyright (C) secunet Security Networks AG
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
#include "migrate_job.h"
18
19
#include <daemon.h>
20
21
#include <config/child_cfg.h>
22
23
24
typedef struct private_migrate_job_t private_migrate_job_t;
25
26
/**
27
 * Private data of a migrate_job_t object.
28
 */
29
struct private_migrate_job_t {
30
  /**
31
   * Public migrate_job_t interface.
32
   */
33
  migrate_job_t public;
34
35
  /**
36
   * reqid of the CHILD_SA if it already exists
37
   */
38
  uint32_t reqid;
39
40
  /**
41
   * source traffic selector
42
   */
43
  traffic_selector_t *src_ts;
44
45
  /**
46
   * destination traffic selector
47
   */
48
  traffic_selector_t *dst_ts;
49
50
  /**
51
   * local host address to be used for IKE
52
   */
53
  host_t *local;
54
55
  /**
56
   * remote host address to be used for IKE
57
   */
58
  host_t *remote;
59
};
60
61
METHOD(job_t, destroy, void,
62
  private_migrate_job_t *this)
63
0
{
64
0
  DESTROY_IF(this->src_ts);
65
0
  DESTROY_IF(this->dst_ts);
66
0
  DESTROY_IF(this->local);
67
0
  DESTROY_IF(this->remote);
68
0
  free(this);
69
0
}
70
71
METHOD(job_t, execute, job_requeue_t,
72
  private_migrate_job_t *this)
73
0
{
74
0
  enumerator_t *ike_sas, *children;
75
0
  ike_sa_t *ike_sa;
76
77
0
  ike_sas = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager,
78
0
                            TRUE);
79
0
  while (ike_sas->enumerate(ike_sas, &ike_sa))
80
0
  {
81
0
    child_sa_t *current, *child_sa = NULL;
82
0
    linked_list_t *vips;
83
0
    status_t status;
84
0
    host_t *host;
85
86
0
    children = ike_sa->create_child_sa_enumerator(ike_sa);
87
0
    while (children->enumerate(children, &current))
88
0
    {
89
0
      if (current->get_reqid(current) == this->reqid)
90
0
      {
91
0
        child_sa = current;
92
0
        break;
93
0
      }
94
0
    }
95
0
    children->destroy(children);
96
97
0
    if (!child_sa)
98
0
    {
99
0
      continue;
100
0
    }
101
102
0
    DBG2(DBG_JOB, "found CHILD_SA with reqid {%u}", this->reqid);
103
104
0
    ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
105
106
0
    host = this->local->clone(this->local);
107
0
    host->set_port(host, charon->socket->get_port(charon->socket, FALSE));
108
0
    ike_sa->set_my_host(ike_sa, host);
109
110
0
    host = this->remote->clone(this->remote);
111
0
    host->set_port(host, IKEV2_UDP_PORT);
112
0
    ike_sa->set_other_host(ike_sa, host);
113
114
0
    vips = linked_list_create_from_enumerator(
115
0
              ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE));
116
117
0
    status = child_sa->update(child_sa, this->local, this->remote, vips,
118
0
                  ike_sa->has_condition(ike_sa, COND_NAT_ANY));
119
0
    switch (status)
120
0
    {
121
0
      case NOT_SUPPORTED:
122
0
        ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
123
0
                     child_sa->get_spi(child_sa, TRUE));
124
0
        break;
125
0
      case SUCCESS:
126
0
        charon->child_sa_manager->remove(charon->child_sa_manager,
127
0
                         child_sa);
128
0
        charon->child_sa_manager->add(charon->child_sa_manager,
129
0
                        child_sa, ike_sa);
130
0
      default:
131
0
        break;
132
0
    }
133
0
    vips->destroy(vips);
134
0
  }
135
0
  ike_sas->destroy(ike_sas);
136
0
  return JOB_REQUEUE_NONE;
137
0
}
138
139
METHOD(job_t, get_priority, job_priority_t,
140
  private_migrate_job_t *this)
141
0
{
142
0
  return JOB_PRIO_MEDIUM;
143
0
}
144
145
/*
146
 * Described in header
147
 */
148
migrate_job_t *migrate_job_create(uint32_t reqid,
149
                  traffic_selector_t *src_ts,
150
                  traffic_selector_t *dst_ts,
151
                  policy_dir_t dir,
152
                  host_t *local, host_t *remote)
153
0
{
154
0
  private_migrate_job_t *this;
155
156
0
  INIT(this,
157
0
    .public = {
158
0
      .job_interface = {
159
0
        .execute = _execute,
160
0
        .get_priority = _get_priority,
161
0
        .destroy = _destroy,
162
0
      },
163
0
    },
164
0
    .reqid = reqid,
165
0
    .src_ts = (dir == POLICY_OUT) ? src_ts : dst_ts,
166
0
    .dst_ts = (dir == POLICY_OUT) ? dst_ts : src_ts,
167
0
    .local = local,
168
0
    .remote = remote,
169
0
  );
170
171
0
  return &this->public;
172
0
}