pluto: Migrated get_my_cpi to libhydra's kernel interface.
This commit is contained in:
+11
-32
@@ -287,47 +287,26 @@ ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr,
|
|||||||
/* Generate Unique CPI numbers.
|
/* Generate Unique CPI numbers.
|
||||||
* The result is returned as an SPI (4 bytes) in network order!
|
* The result is returned as an SPI (4 bytes) in network order!
|
||||||
* The real bits are in the nework-low-order 2 bytes.
|
* The real bits are in the nework-low-order 2 bytes.
|
||||||
* Modelled on get_ipsec_spi, but range is more limited:
|
|
||||||
* 256-61439.
|
|
||||||
* If we can't find one easily, return 0 (a bad SPI,
|
|
||||||
* no matter what order) indicating failure.
|
|
||||||
*/
|
*/
|
||||||
ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel)
|
ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel)
|
||||||
{
|
{
|
||||||
static cpi_t first_busy_cpi = 0, latest_cpi;
|
host_t *host_src, *host_dst;
|
||||||
char text_said[SATOT_BUF];
|
u_int16_t cpi;
|
||||||
rng_t *rng;
|
|
||||||
|
|
||||||
set_text_said(text_said, &sr->this.host_addr, 0, IPPROTO_COMP);
|
host_src = host_create_from_sockaddr((sockaddr_t*)&sr->that.host_addr);
|
||||||
|
host_dst = host_create_from_sockaddr((sockaddr_t*)&sr->this.host_addr);
|
||||||
|
|
||||||
|
if (hydra->kernel_interface->get_cpi(hydra->kernel_interface, host_src,
|
||||||
|
host_dst, sr->reqid, &cpi) != SUCCESS)
|
||||||
|
|
||||||
if (kernel_ops->get_spi)
|
|
||||||
{
|
{
|
||||||
return kernel_ops->get_spi(&sr->that.host_addr
|
cpi = 0;
|
||||||
, &sr->this.host_addr, IPPROTO_COMP, tunnel
|
|
||||||
, get_proto_reqid(sr->reqid, IPPROTO_COMP)
|
|
||||||
, IPCOMP_FIRST_NEGOTIATED, IPCOMP_LAST_NEGOTIATED
|
|
||||||
, text_said);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
host_src->destroy(host_src);
|
||||||
while (!(IPCOMP_FIRST_NEGOTIATED <= first_busy_cpi && first_busy_cpi < IPCOMP_LAST_NEGOTIATED))
|
host_dst->destroy(host_dst);
|
||||||
{
|
|
||||||
rng->get_bytes(rng, sizeof(first_busy_cpi), (u_char *)&first_busy_cpi);
|
|
||||||
latest_cpi = first_busy_cpi;
|
|
||||||
}
|
|
||||||
rng->destroy(rng);
|
|
||||||
|
|
||||||
latest_cpi++;
|
return htonl((u_int32_t)ntohs(cpi));
|
||||||
|
|
||||||
if (latest_cpi == first_busy_cpi)
|
|
||||||
{
|
|
||||||
find_my_cpi_gap(&latest_cpi, &first_busy_cpi);
|
|
||||||
}
|
|
||||||
if (latest_cpi > IPCOMP_LAST_NEGOTIATED)
|
|
||||||
{
|
|
||||||
latest_cpi = IPCOMP_FIRST_NEGOTIATED;
|
|
||||||
}
|
|
||||||
return htonl((ipsec_spi_t)latest_cpi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace the shell metacharacters ', \, ", `, and $ in a character string
|
/* Replace the shell metacharacters ', \, ", `, and $ in a character string
|
||||||
|
|||||||
@@ -897,56 +897,6 @@ void show_states_status(bool all, const char *name)
|
|||||||
free(array);
|
free(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given that we've used up a range of unused CPI's,
|
|
||||||
* search for a new range of currently unused ones.
|
|
||||||
* Note: this is very expensive when not trivial!
|
|
||||||
* If we can't find one easily, choose 0 (a bad SPI,
|
|
||||||
* no matter what order) indicating failure.
|
|
||||||
*/
|
|
||||||
void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
|
|
||||||
{
|
|
||||||
int tries = 0;
|
|
||||||
cpi_t base = *latest_cpi;
|
|
||||||
cpi_t closest;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
startover:
|
|
||||||
closest = ~0; /* not close at all */
|
|
||||||
for (i = 0; i < STATE_TABLE_SIZE; i++)
|
|
||||||
{
|
|
||||||
struct state *st;
|
|
||||||
|
|
||||||
for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
|
|
||||||
{
|
|
||||||
if (st->st_ipcomp.present)
|
|
||||||
{
|
|
||||||
cpi_t c = ntohl(st->st_ipcomp.our_spi) - base;
|
|
||||||
|
|
||||||
if (c < closest)
|
|
||||||
{
|
|
||||||
if (c == 0)
|
|
||||||
{
|
|
||||||
/* oops: next spot is occupied; start over */
|
|
||||||
if (++tries == 20)
|
|
||||||
{
|
|
||||||
/* FAILURE */
|
|
||||||
*latest_cpi = *first_busy_cpi = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
base++;
|
|
||||||
if (base > IPCOMP_LAST_NEGOTIATED)
|
|
||||||
base = IPCOMP_FIRST_NEGOTIATED;
|
|
||||||
goto startover; /* really a tail call */
|
|
||||||
}
|
|
||||||
closest = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*latest_cpi = base; /* base is first in next free range */
|
|
||||||
*first_busy_cpi = closest + base; /* and this is the roof */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Muck with high-order 16 bits of this SPI in order to make
|
/* Muck with high-order 16 bits of this SPI in order to make
|
||||||
* the corresponding SAID unique.
|
* the corresponding SAID unique.
|
||||||
* Its low-order 16 bits hold a well-known IPCOMP CPI.
|
* Its low-order 16 bits hold a well-known IPCOMP CPI.
|
||||||
|
|||||||
@@ -267,7 +267,6 @@ extern struct state
|
|||||||
|
|
||||||
extern void show_states_status(bool all, const char *name);
|
extern void show_states_status(bool all, const char *name);
|
||||||
extern void for_each_state(void *(f)(struct state *, void *data), void *data);
|
extern void for_each_state(void *(f)(struct state *, void *data), void *data);
|
||||||
extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi);
|
|
||||||
extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
|
extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
|
||||||
extern void fmt_state(bool all, struct state *st, time_t n
|
extern void fmt_state(bool all, struct state *st, time_t n
|
||||||
, char *state_buf, size_t state_buf_len
|
, char *state_buf, size_t state_buf_len
|
||||||
|
|||||||
Reference in New Issue
Block a user