[strongSwan-dev] [PATCH] charon: per connection replay window configuration
Christophe Gouault
christophe.gouault at 6wind.com
Tue Apr 29 10:14:45 CEST 2014
From: Zheng Zhong <zhong.zheng at 6wind.com>
Make replay window configurable per connection.
A new ipsec.conf option is available in the conn section:
replay_window 32
If unset, then the default value from strongswan.conf is used
(charon.replay_window).
Like for charon.replay_window, this option is only taken into
account by the netlink kernel interface.
Signed-off-by: Zheng Zhong <zhong.zheng at 6wind.com>
Acked-by: Christophe Gouault <christophe.gouault at 6wind.com>
---
src/libcharon/config/child_cfg.c | 20 +++++++
src/libcharon/config/child_cfg.h | 14 +++++
src/libcharon/plugins/stroke/stroke_config.c | 1 +
src/libcharon/sa/child_sa.c | 6 ++-
src/libhydra/kernel/kernel_interface.c | 9 ++--
src/libhydra/kernel/kernel_interface.h | 4 +-
src/libhydra/kernel/kernel_ipsec.h | 4 +-
.../plugins/kernel_klips/kernel_klips_ipsec.c | 3 +-
.../plugins/kernel_netlink/kernel_netlink_ipsec.c | 56 +++++++++++++-------
.../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 3 +-
src/starter/args.c | 1 +
src/starter/confread.c | 2 +
src/starter/confread.h | 1 +
src/starter/keywords.h | 1 +
src/starter/keywords.txt | 1 +
src/starter/starterstroke.c | 1 +
src/stroke/stroke_msg.h | 1 +
17 files changed, 99 insertions(+), 29 deletions(-)
diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c
index 8d8214e..63fea5a 100644
--- a/src/libcharon/config/child_cfg.c
+++ b/src/libcharon/config/child_cfg.c
@@ -138,6 +138,11 @@ struct private_child_cfg_t {
* enable installation and removal of kernel IPsec policies
*/
bool install_policy;
+
+ /**
+ * anti-replay window size
+ */
+ u_int32_t replay_window;
};
METHOD(child_cfg_t, get_name, char*,
@@ -478,6 +483,18 @@ METHOD(child_cfg_t, get_tfc, u_int32_t,
return this->tfc;
}
+METHOD(child_cfg_t, get_replay_window, u_int32_t,
+ private_child_cfg_t *this)
+{
+ return this->replay_window;
+}
+
+METHOD(child_cfg_t, set_replay_window, void,
+ private_child_cfg_t *this, u_int32_t replay_window)
+{
+ this->replay_window = replay_window;
+}
+
METHOD(child_cfg_t, set_mipv6_options, void,
private_child_cfg_t *this, bool proxy_mode, bool install_policy)
{
@@ -555,6 +572,8 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
.get_reqid = _get_reqid,
.get_mark = _get_mark,
.get_tfc = _get_tfc,
+ .get_replay_window = _get_replay_window,
+ .set_replay_window = _set_replay_window,
.use_proxy_mode = _use_proxy_mode,
.install_policy = _install_policy,
.get_ref = _get_ref,
@@ -577,6 +596,7 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
.my_ts = linked_list_create(),
.other_ts = linked_list_create(),
.tfc = tfc,
+ .replay_window = -1,
);
if (mark_in)
diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h
index 20d1fa8..8e3e4cf 100644
--- a/src/libcharon/config/child_cfg.h
+++ b/src/libcharon/config/child_cfg.h
@@ -235,6 +235,20 @@ struct child_cfg_t {
u_int32_t (*get_tfc)(child_cfg_t *this);
/**
+ * Get anti-replay window size
+ *
+ * @return anti-replay window size
+ */
+ u_int32_t (*get_replay_window)(child_cfg_t *this);
+
+ /**
+ * Set anti-replay window size
+ *
+ * @param window anti-replay window size
+ */
+ void (*set_replay_window)(child_cfg_t *this, u_int32_t window);
+
+ /**
* Sets two options needed for Mobile IPv6 interoperability.
*
* @param proxy_mode use IPsec transport proxy mode (default FALSE)
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index e5e6d92..ca68e24 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -1149,6 +1149,7 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
map_action(msg->add_conn.close_action), msg->add_conn.ipcomp,
msg->add_conn.inactivity, msg->add_conn.reqid,
&mark_in, &mark_out, msg->add_conn.tfc);
+ child_cfg->set_replay_window(child_cfg, msg->add_conn.replay_window);
child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode,
msg->add_conn.install_policy);
add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index 720a585..0c9a847 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -639,6 +639,7 @@ METHOD(child_sa_t, install, status_t,
host_t *src, *dst;
status_t status;
bool update = FALSE;
+ u_int32_t replay_window = 0;
/* now we have to decide which spi to use. Use self allocated, if "in",
* or the one in the proposal, if not "in" (others). Additionally,
@@ -653,6 +654,7 @@ METHOD(child_sa_t, install, status_t,
}
this->my_spi = spi;
this->my_cpi = cpi;
+ replay_window = this->config->get_replay_window(this->config);
}
else
{
@@ -722,8 +724,8 @@ METHOD(child_sa_t, install, status_t,
src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
inbound ? this->mark_in : this->mark_out, tfc,
lifetime, enc_alg, encr, int_alg, integ, this->mode,
- this->ipcomp, cpi, initiator, this->encap, esn, update,
- src_ts, dst_ts);
+ this->ipcomp, replay_window, cpi, initiator, this->encap,
+ esn, update, src_ts, dst_ts);
free(lifetime);
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c
index 3e34d20..30e4a45 100644
--- a/src/libhydra/kernel/kernel_interface.c
+++ b/src/libhydra/kernel/kernel_interface.c
@@ -179,9 +179,9 @@ METHOD(kernel_interface_t, add_sa, status_t,
private_kernel_interface_t *this, host_t *src, host_t *dst,
u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int32_t replay_window, u_int16_t cpi, bool initiator, bool encap, bool esn,
+ bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
if (!this->ipsec)
{
@@ -189,7 +189,8 @@ METHOD(kernel_interface_t, add_sa, status_t,
}
return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
- ipcomp, cpi, initiator, encap, esn, inbound, src_ts, dst_ts);
+ ipcomp, replay_window, cpi, initiator, encap, esn, inbound,
+ src_ts, dst_ts);
}
METHOD(kernel_interface_t, update_sa, status_t,
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h
index cc47d3c..ad13f6e 100644
--- a/src/libhydra/kernel/kernel_interface.h
+++ b/src/libhydra/kernel/kernel_interface.h
@@ -144,6 +144,7 @@ struct kernel_interface_t {
* @param int_key key to use for integrity protection
* @param mode mode of the SA (tunnel, transport)
* @param ipcomp IPComp transform to use
+ * @param replay_window anti-replay window size
* @param cpi CPI for IPComp
* @param initiator TRUE if initiator of the exchange creating this SA
* @param encap enable UDP encapsulation for NAT traversal
@@ -159,7 +160,8 @@ struct kernel_interface_t {
u_int32_t tfc, lifetime_cfg_t *lifetime,
u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key,
- ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
+ ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int32_t replay_window, u_int16_t cpi,
bool initiator, bool encap, bool esn, bool inbound,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h
index 25f5b38..43f5f3d 100644
--- a/src/libhydra/kernel/kernel_ipsec.h
+++ b/src/libhydra/kernel/kernel_ipsec.h
@@ -100,6 +100,7 @@ struct kernel_ipsec_t {
* @param int_key key to use for integrity protection
* @param mode mode of the SA (tunnel, transport)
* @param ipcomp IPComp transform to use
+ * @param replay_window anti-replay window size
* @param cpi CPI for IPComp
* @param initiator TRUE if initiator of the exchange creating this SA
* @param encap enable UDP encapsulation for NAT traversal
@@ -115,7 +116,8 @@ struct kernel_ipsec_t {
mark_t mark, u_int32_t tfc, lifetime_cfg_t *lifetime,
u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key,
- ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
+ ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int32_t replay_window, u_int16_t cpi,
bool initiator, bool encap, bool esn, bool inbound,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
index a75ccf3..fec1410 100644
--- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
+++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
@@ -1682,7 +1682,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
- u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn,
+ u_int16_t ipcomp, u_int32_t replay_window, u_int16_t cpi,
+ bool initiator, bool encap, bool esn,
bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
unsigned char request[PFKEY_BUFFER_SIZE];
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index c864a92..76a8c7b 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -631,11 +631,12 @@ static inline u_int32_t get_priority(policy_entry_t *policy,
}
/**
- * Return the length of the ESN bitmap
+ * Return the length of the replay bitmap in number of __u32 blocks
*/
-static inline size_t esn_bmp_len(private_kernel_netlink_ipsec_t *this)
+static inline u_int32_t replay_bmp_len(u_int32_t replay_window)
{
- return this->replay_bmp * sizeof(u_int32_t);
+ return (replay_window + sizeof(u_int32_t) * 8 - 1) /
+ (sizeof(u_int32_t) * 8);
}
/**
@@ -1195,7 +1196,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,
+ u_int32_t replay_window, u_int16_t cpi,
+ bool initiator, bool encap, bool esn, bool inbound,
traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
{
netlink_buf_t request;
@@ -1205,6 +1207,20 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int16_t icv_size = 64;
ipsec_mode_t original_mode = mode;
status_t status = FAILED;
+ u_int32_t replay_bmp;
+
+ if (replay_window == UINT32_C(-1) ||
+ replay_window == this->replay_window)
+ {
+ /* default replay_window parameters */
+ replay_window = this->replay_window;
+ replay_bmp = this->replay_bmp;
+ }
+ else
+ {
+ /* sa-specific replay_window parameters */
+ replay_bmp = replay_bmp_len(replay_window);
+ }
/* if IPComp is used, we install an additional IPComp SA. if the cpi is 0
* we are in the recursive call below */
@@ -1213,8 +1229,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
- chunk_empty, mode, ipcomp, 0, initiator, FALSE, FALSE, inbound,
- src_ts, dst_ts);
+ chunk_empty, mode, ipcomp, replay_window, 0, initiator,
+ FALSE, FALSE, inbound, src_ts, dst_ts);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
mode = MODE_TRANSPORT;
@@ -1480,23 +1496,23 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (protocol != IPPROTO_COMP)
{
- if (esn || this->replay_window > DEFAULT_REPLAY_WINDOW)
+ if (esn || replay_window > DEFAULT_REPLAY_WINDOW)
{
/* for ESN or larger replay windows we need the new
* XFRMA_REPLAY_ESN_VAL attribute to configure a bitmap */
struct xfrm_replay_state_esn *replay;
replay = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL,
- sizeof(*replay) + esn_bmp_len(this));
+ sizeof(*replay) + replay_bmp * sizeof(u_int32_t));
if (!replay)
{
goto failed;
}
/* bmp_len contains number uf __u32's */
- replay->bmp_len = this->replay_bmp;
- replay->replay_window = this->replay_window;
+ replay->bmp_len = replay_bmp;
+ replay->replay_window = replay_window;
DBG2(DBG_KNL, " using replay window of %u packets",
- this->replay_window);
+ replay_window);
if (esn)
{
@@ -1507,8 +1523,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
else
{
DBG2(DBG_KNL, " using replay window of %u packets",
- this->replay_window);
- sa->replay_window = this->replay_window;
+ replay_window);
+ sa->replay_window = replay_window;
}
}
@@ -1542,6 +1558,7 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
u_int32_t spi, u_int8_t protocol,
host_t *dst, mark_t mark,
struct xfrm_replay_state_esn **replay_esn,
+ u_int32_t *replay_esn_len,
struct xfrm_replay_state **replay)
{
netlink_buf_t request;
@@ -1618,9 +1635,10 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
break;
}
if (rta->rta_type == XFRMA_REPLAY_ESN_VAL &&
- RTA_PAYLOAD(rta) >= sizeof(**replay_esn) + esn_bmp_len(this))
+ RTA_PAYLOAD(rta) >= sizeof(**replay_esn))
{
*replay_esn = malloc(RTA_PAYLOAD(rta));
+ *replay_esn_len = RTA_PAYLOAD(rta);
memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta));
break;
}
@@ -1804,6 +1822,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
struct xfrm_encap_tmpl* tmpl = NULL;
struct xfrm_replay_state *replay = NULL;
struct xfrm_replay_state_esn *replay_esn = NULL;
+ u_int32_t replay_esn_len;
status_t status = FAILED;
/* if IPComp is used, we first update the IPComp SA */
@@ -1868,7 +1887,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
goto failed;
}
- get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay);
+ get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay_esn_len, &replay);
/* delete the old SA (without affecting the IPComp SA) */
if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)
@@ -1936,12 +1955,12 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
struct xfrm_replay_state_esn *state;
state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL,
- sizeof(*state) + esn_bmp_len(this));
+ replay_esn_len);
if (!state)
{
goto failed;
}
- memcpy(state, replay_esn, sizeof(*state) + esn_bmp_len(this));
+ memcpy(state, replay_esn, replay_esn_len);
}
else if (replay)
{
@@ -2690,8 +2709,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
"%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),
);
- this->replay_bmp = (this->replay_window + sizeof(u_int32_t) * 8 - 1) /
- (sizeof(u_int32_t) * 8);
+ this->replay_bmp = replay_bmp_len(this->replay_window);
if (streq(lib->ns, "starter"))
{ /* starter has no threads, so we do not register for kernel events */
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index d82d672..9a5c385 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1615,7 +1615,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
- u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn,
+ u_int16_t ipcomp, u_int32_t replay_window, u_int16_t cpi,
+ bool initiator, bool encap, bool esn,
bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
unsigned char request[PFKEY_BUFFER_SIZE];
diff --git a/src/starter/args.c b/src/starter/args.c
index f5a617e..0d662f4 100644
--- a/src/starter/args.c
+++ b/src/starter/args.c
@@ -173,6 +173,7 @@ static const token_info_t token_info[] =
{ ARG_STR, offsetof(starter_conn_t, me_mediated_by), NULL },
{ ARG_STR, offsetof(starter_conn_t, me_peerid), NULL },
{ ARG_UINT, offsetof(starter_conn_t, reqid), NULL },
+ { ARG_UINT, offsetof(starter_conn_t, replay_window), NULL },
{ ARG_MISC, 0, NULL /* KW_MARK */ },
{ ARG_MISC, 0, NULL /* KW_MARK_IN */ },
{ ARG_MISC, 0, NULL /* KW_MARK_OUT */ },
diff --git a/src/starter/confread.c b/src/starter/confread.c
index 19178a2..0fac895 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -34,6 +34,7 @@
#define SA_REPLACEMENT_MARGIN_DEFAULT 540 /* 9 minutes */
#define SA_REPLACEMENT_FUZZ_DEFAULT 100 /* 100% of margin */
#define SA_REPLACEMENT_RETRIES_DEFAULT 3
+#define SA_REPLAY_WINDOW_DEFAULT -1 /* use charon.replay_window */
static const char ike_defaults[] = "aes128-sha1-modp2048,3des-sha1-modp1536";
static const char esp_defaults[] = "aes128-sha1,3des-sha1";
@@ -132,6 +133,7 @@ static void default_values(starter_config_t *cfg)
cfg->conn_default.install_policy = TRUE;
cfg->conn_default.dpd_delay = 30; /* seconds */
cfg->conn_default.dpd_timeout = 150; /* seconds */
+ cfg->conn_default.replay_window = SA_REPLAY_WINDOW_DEFAULT;
cfg->conn_default.left.seen = SEEN_NONE;
cfg->conn_default.right.seen = SEEN_NONE;
diff --git a/src/starter/confread.h b/src/starter/confread.h
index d55a17e..a32f8cb 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -162,6 +162,7 @@ struct starter_conn {
u_int32_t reqid;
mark_t mark_in;
mark_t mark_out;
+ u_int32_t replay_window;
u_int32_t tfc;
bool install_policy;
bool aggressive;
diff --git a/src/starter/keywords.h b/src/starter/keywords.h
index 705a7c1..5b6b28b 100644
--- a/src/starter/keywords.h
+++ b/src/starter/keywords.h
@@ -69,6 +69,7 @@ typedef enum {
KW_MEDIATED_BY,
KW_ME_PEERID,
KW_REQID,
+ KW_REPLAY_WINDOW,
KW_MARK,
KW_MARK_IN,
KW_MARK_OUT,
diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt
index ad915bf..ee0bd31 100644
--- a/src/starter/keywords.txt
+++ b/src/starter/keywords.txt
@@ -69,6 +69,7 @@ mediation, KW_MEDIATION
mediated_by, KW_MEDIATED_BY
me_peerid, KW_ME_PEERID
reqid, KW_REQID
+replay_window, KW_REPLAY_WINDOW
mark, KW_MARK
mark_in, KW_MARK_IN
mark_out, KW_MARK_OUT
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index fca4b1e..839e66e 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -202,6 +202,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
msg.add_conn.ikeme.mediated_by = push_string(&msg, conn->me_mediated_by);
msg.add_conn.ikeme.peerid = push_string(&msg, conn->me_peerid);
msg.add_conn.reqid = conn->reqid;
+ msg.add_conn.replay_window = conn->replay_window;
msg.add_conn.mark_in.value = conn->mark_in.value;
msg.add_conn.mark_in.mask = conn->mark_in.mask;
msg.add_conn.mark_out.value = conn->mark_out.value;
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 5ece724..60886cf 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -304,6 +304,7 @@ struct stroke_msg_t {
u_int32_t mask;
} mark_in, mark_out;
stroke_end_t me, other;
+ u_int32_t replay_window;
} add_conn;
/* data for STR_ADD_CA */
--
1.7.10.4
More information about the Dev
mailing list