pluto: Removed KLIPS specific bare shunt scanning.

This commit is contained in:
Tobias Brunner 2010-07-20 13:25:29 +02:00
parent 749d3cccaf
commit 54f42e350e
5 changed files with 0 additions and 340 deletions

View File

@ -77,7 +77,6 @@ ENUM(dpd_action_names, DPD_ACTION_NONE, DPD_ACTION_RESTART,
ENUM(timer_event_names, EVENT_NULL, EVENT_LOG_DAILY,
"EVENT_NULL",
"EVENT_REINIT_SECRET",
"EVENT_SHUNT_SCAN",
"EVENT_SO_DISCARD",
"EVENT_RETRANSMIT",
"EVENT_SA_REPLACE",

View File

@ -246,9 +246,6 @@ extern enum_name_t *timer_event_names;
enum event_type {
EVENT_NULL, /* non-event */
EVENT_REINIT_SECRET, /* Refresh cookie secret */
#ifdef KLIPS
EVENT_SHUNT_SCAN, /* scan shunt eroutes known to kernel */
#endif
EVENT_SO_DISCARD, /* discard unfinished state object */
EVENT_RETRANSMIT, /* Retransmit packet */
EVENT_SA_REPLACE, /* SA replacement event */

View File

@ -1343,328 +1343,6 @@ static bool shunt_eroute(connection_t *c, struct spd_route *sr,
, null_proto_info, op, opname) && ok;
}
/*
* This is only called when s is a likely SAID with trailing protocol i.e.
* it has the form :-
*
* %<keyword>:p
* <ip-proto><spi>@a.b.c.d:p
*
* The task here is to remove the ":p" part so that the rest can be read
* by another routine.
*/
static const char *read_proto(const char * s, size_t * len, int * transport_proto)
{
const char * p;
const char * ugh;
unsigned long proto;
size_t l;
l = *len;
p = memchr(s, ':', l);
if (p == 0)
{
*transport_proto = 0;
return 0;
}
ugh = ttoul(p+1, l-((p-s)+1), 10, &proto);
if (ugh != 0)
{
return ugh;
}
if (proto > 65535)
{
return "protocol number is too large, legal range is 0-65535";
}
*len = p-s;
*transport_proto = proto;
return 0;
}
/* scan /proc/net/ipsec_eroute every once in a while, looking for:
*
* - %hold shunts of which Pluto isn't aware. This situation could
* be caused by lost ACQUIRE messages. When found, they will
* added to orphan_holds. This in turn will lead to Opportunistic
* initiation.
*
* - other kinds of shunts that haven't been used recently. These will be
* deleted. They represent OE failures.
*
* - recording recent uses of tunnel eroutes so that rekeying decisions
* can be made for OE connections.
*
* Here are some sample lines:
* 10 10.3.2.1.0/24 -> 0.0.0.0/0 => %trap
* 259 10.3.2.1.115/32 -> 10.19.75.161/32 => tun0x1002@10.19.75.145
* 71 10.44.73.97/32 -> 0.0.0.0/0 => %trap
* 4119 10.44.73.97/32 -> 10.114.121.41/32 => %pass
* Newer versions of KLIPS start each line with a 32-bit packet count.
* If available, the count is used to detect whether a %pass shunt is in use.
*
* NOTE: execution time is quadratic in the number of eroutes since the
* searching for each is sequential. If this becomes a problem, faster
* searches could be implemented (hash or radix tree, for example).
*/
void scan_proc_shunts(void)
{
static const char procname[] = "/proc/net/ipsec_eroute";
FILE *f;
time_t nw = now();
int lino;
struct eroute_info *expired = NULL;
event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
DBG(DBG_CONTROL,
DBG_log("scanning for shunt eroutes")
)
/* free any leftover entries: they will be refreshed if still current */
while (orphaned_holds != NULL)
{
struct eroute_info *p = orphaned_holds;
orphaned_holds = p->next;
free(orphaned_holds);
}
/* decode the /proc file. Don't do anything strenuous to it
* (certainly no PF_KEY stuff) to minimize the chance that it
* might change underfoot.
*/
f = fopen(procname, "r");
if (f == NULL)
{
return;
}
/* for each line... */
for (lino = 1; ; lino++)
{
unsigned char buf[1024]; /* should be big enough */
chunk_t field[10]; /* 10 is loose upper bound */
chunk_t *ff = NULL; /* fixed fields (excluding optional count) */
int fi;
struct eroute_info eri;
char *cp;
err_t context = ""
, ugh = NULL;
cp = fgets(buf, sizeof(buf), f);
if (cp == NULL)
{
break;
}
/* break out each field
* Note: if there are too many fields, just stop;
* it will be diagnosed a little later.
*/
for (fi = 0; fi < (int)countof(field); fi++)
{
static const char sep[] = " \t\n"; /* field-separating whitespace */
size_t w;
cp += strspn(cp, sep); /* find start of field */
w = strcspn(cp, sep); /* find width of field */
field[fi] = chunk_create(cp, w);
cp += w;
if (w == 0)
{
break;
}
}
/* This odd do-hickey is to share error reporting code.
* A break will get to that common code. The setting
* of "ugh" and "context" parameterize it.
*/
do {
/* Old entries have no packet count; new ones do.
* check if things are as they should be.
*/
if (fi == 5)
{
ff = &field[0]; /* old form, with no count */
}
else if (fi == 6)
{
ff = &field[1]; /* new form, with count */
}
else
{
ugh = "has wrong number of fields";
break;
}
if (ff[1].len != 2
|| strncmp(ff[1].ptr, "->", 2) != 0
|| ff[3].len != 2
|| strncmp(ff[3].ptr, "=>", 2) != 0)
{
ugh = "is missing -> or =>";
break;
}
/* actually digest fields of interest */
/* packet count */
eri.count = 0;
if (ff != field)
{
context = "count field is malformed: ";
ugh = ttoul(field[0].ptr, field[0].len, 10, &eri.count);
if (ugh != NULL)
{
break;
}
}
/* our client */
context = "source subnet field malformed: ";
ugh = ttosubnet(ff[0].ptr, ff[0].len, AF_INET, &eri.ours);
if (ugh != NULL)
{
break;
}
/* his client */
context = "destination subnet field malformed: ";
ugh = ttosubnet(ff[2].ptr, ff[2].len, AF_INET, &eri.his);
if (ugh != NULL)
{
break;
}
/* SAID */
context = "SA ID field malformed: ";
ugh = read_proto(ff[4].ptr, &ff[4].len, &eri.transport_proto);
if (ugh != NULL)
{
break;
}
ugh = ttosa(ff[4].ptr, ff[4].len, &eri.said);
} while (FALSE);
if (ugh != NULL)
{
plog("INTERNAL ERROR: %s line %d %s%s"
, procname, lino, context, ugh);
continue; /* ignore rest of line */
}
/* Now we have decoded eroute, let's consider it.
* For shunt eroutes:
*
* %hold: if not known, add to orphaned_holds list for initiation
* because ACQUIRE might have been lost.
*
* %pass, %drop, %reject: determine if idle; if so, blast it away.
* Can occur bare (if DNS provided insufficient information)
* or with a connection (failure context).
* Could even be installed by ipsec manual.
*
* %trap: always welcome.
*
* For other eroutes: find state and record count change
*/
if (eri.said.proto == SA_INT)
{
/* shunt eroute */
switch (ntohl(eri.said.spi))
{
case SPI_HOLD:
if (bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto) == NULL
&& shunt_owner(&eri.ours, &eri.his) == NULL)
{
int ourport = ntohs(portof(&eri.ours.addr));
int hisport = ntohs(portof(&eri.his.addr));
char ourst[SUBNETTOT_BUF];
char hist[SUBNETTOT_BUF];
char sat[SATOT_BUF];
subnettot(&eri.ours, 0, ourst, sizeof(ourst));
subnettot(&eri.his, 0, hist, sizeof(hist));
satot(&eri.said, 0, sat, sizeof(sat));
DBG(DBG_CONTROL,
DBG_log("add orphaned shunt %s:%d -> %s:%d => %s:%d"
, ourst, ourport, hist, hisport, sat, eri.transport_proto)
)
eri.next = orphaned_holds;
orphaned_holds = clone_thing(eri);
}
break;
case SPI_PASS:
case SPI_DROP:
case SPI_REJECT:
/* nothing sensible to do if we don't have counts */
if (ff != field)
{
struct bare_shunt **bs_pp
= bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto);
if (bs_pp != NULL)
{
struct bare_shunt *bs = *bs_pp;
if (eri.count != bs->count)
{
bs->count = eri.count;
bs->last_activity = nw;
}
else if (nw - bs->last_activity > SHUNT_PATIENCE)
{
eri.next = expired;
expired = clone_thing(eri);
}
}
}
break;
case SPI_TRAP:
break;
default:
bad_case(ntohl(eri.said.spi));
}
}
else
{
/* regular (non-shunt) eroute */
state_eroute_usage(&eri.ours, &eri.his, eri.count, nw);
}
} /* for each line */
fclose(f);
/* Now that we've finished processing the /proc file,
* it is safe to delete the expired %pass shunts.
*/
while (expired != NULL)
{
struct eroute_info *p = expired;
ip_address src, dst;
networkof(&p->ours, &src);
networkof(&p->his, &dst);
(void) replace_bare_shunt(&src, &dst
, BOTTOM_PRIO /* not used because we are deleting. This value is a filler */
, SPI_PASS /* not used because we are deleting. This value is a filler */
, FALSE, p->transport_proto, "delete expired bare shunts");
expired = p->next;
free(p);
}
}
static bool del_spi(ipsec_spi_t spi, int proto,
const ip_address *src, const ip_address *dest)
{
@ -2371,11 +2049,6 @@ void init_kernel(void)
/* register SA types that we can negotiate */
can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
kernel_ops->pfkey_register();
if (!kernel_ops->policy_lifetime)
{
event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
}
#endif
}

View File

@ -152,8 +152,6 @@ extern void record_and_initiate_opportunistic(const ip_subnet *
extern void init_kernel(void);
extern void scan_proc_shunts(void);
extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c);

View File

@ -233,13 +233,6 @@ void handle_timer_event(void)
init_secret();
break;
#ifdef KLIPS
case EVENT_SHUNT_SCAN:
passert(st == NULL);
scan_proc_shunts();
break;
#endif
case EVENT_LOG_DAILY:
daily_log_event();
break;