Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/libalias/alias_db.c
Show First 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | |||||
/* Dummy port number codes used for FindLinkIn/Out() and AddLink(). | /* Dummy port number codes used for FindLinkIn/Out() and AddLink(). | ||||
These constants can be anything except zero, which indicates an | These constants can be anything except zero, which indicates an | ||||
unknown port number. */ | unknown port number. */ | ||||
#define NO_DEST_PORT 1 | #define NO_DEST_PORT 1 | ||||
#define NO_SRC_PORT 1 | #define NO_SRC_PORT 1 | ||||
/* Dummy address used for FindLinkIn/Out() and AddLink(). | /* Matches any/unknown address in FindLinkIn/Out() and AddLink(). */ | ||||
The value of this variable is never used. */ | static struct in_addr const ANY_ADDR = { INADDR_ANY }; | ||||
static struct in_addr const NO_ADDR; | |||||
/* Data Structures | /* Data Structures | ||||
The fundamental data structure used in this program is | The fundamental data structure used in this program is | ||||
"struct alias_link". Whenever a TCP connection is made, | "struct alias_link". Whenever a TCP connection is made, | ||||
a UDP datagram is sent out, or an ICMP echo request is made, | a UDP datagram is sent out, or an ICMP echo request is made, | ||||
a link record is made (if it has not already been created). | a link record is made (if it has not already been created). | ||||
The link record is identified by the source address/port | The link record is identified by the source address/port | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
/* flag bits */ | /* flag bits */ | ||||
#define LINK_UNKNOWN_DEST_PORT 0x01 | #define LINK_UNKNOWN_DEST_PORT 0x01 | ||||
#define LINK_UNKNOWN_DEST_ADDR 0x02 | #define LINK_UNKNOWN_DEST_ADDR 0x02 | ||||
#define LINK_PERMANENT 0x04 | #define LINK_PERMANENT 0x04 | ||||
#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */ | #define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */ | ||||
#define LINK_UNFIREWALLED 0x08 | #define LINK_UNFIREWALLED 0x08 | ||||
int timestamp; /* Time link was last accessed */ | int timestamp; /* Time link was last accessed */ | ||||
int expire_time; /* Expire time for link */ | |||||
#ifndef NO_USE_SOCKETS | #ifndef NO_USE_SOCKETS | ||||
int sockfd; /* socket descriptor */ | int sockfd; /* socket descriptor */ | ||||
#endif | #endif | ||||
/* Linked list of pointers for input and output lookup tables */ | /* Linked list of pointers for input and output lookup tables */ | ||||
LIST_ENTRY (alias_link) list_out; | union { | ||||
LIST_ENTRY (alias_link) list_in; | struct { | ||||
TAILQ_ENTRY (alias_link) list_expire; | LIST_ENTRY(alias_link) in; | ||||
LIST_ENTRY(alias_link) out; | |||||
} all; | |||||
struct { | |||||
LIST_ENTRY(alias_link) list; | |||||
} pptp; | |||||
}; | |||||
struct { | |||||
TAILQ_ENTRY(alias_link) list; | |||||
int timeout; /* Expire time for link */ | |||||
} expire; | |||||
/* Auxiliary data */ | /* Auxiliary data */ | ||||
union { | union { | ||||
char *frag_ptr; | char *frag_ptr; | ||||
struct in_addr frag_addr; | struct in_addr frag_addr; | ||||
struct tcp_dat *tcp; | struct tcp_dat *tcp; | ||||
} data; | } data; | ||||
}; | }; | ||||
Show All 36 Lines | StartPointOut() -- link table initial search point for | ||||
outgoing packets | outgoing packets | ||||
Miscellaneous: | Miscellaneous: | ||||
SeqDiff() -- difference between two TCP sequences | SeqDiff() -- difference between two TCP sequences | ||||
ShowAliasStats() -- send alias statistics to a monitor file | ShowAliasStats() -- send alias statistics to a monitor file | ||||
*/ | */ | ||||
/* Local prototypes */ | /* Local prototypes */ | ||||
static u_int StartPointIn(struct in_addr, u_short, int); | static struct group_in * | ||||
StartPointIn(struct libalias *, struct in_addr, u_short, int, int); | |||||
static u_int | static u_int | ||||
StartPointOut(struct in_addr, struct in_addr, | StartPointOut(struct in_addr, struct in_addr, u_short, u_short, int); | ||||
u_short, u_short, int); | |||||
static int SeqDiff(u_long, u_long); | static int SeqDiff(u_long, u_long); | ||||
#ifndef NO_FW_PUNCH | #ifndef NO_FW_PUNCH | ||||
/* Firewall control */ | /* Firewall control */ | ||||
static void InitPunchFW(struct libalias *); | static void InitPunchFW(struct libalias *); | ||||
static void UninitPunchFW(struct libalias *); | static void UninitPunchFW(struct libalias *); | ||||
static void ClearFWHole(struct alias_link *); | static void ClearFWHole(struct alias_link *); | ||||
#endif | #endif | ||||
/* Log file control */ | /* Log file control */ | ||||
static void ShowAliasStats(struct libalias *); | static void ShowAliasStats(struct libalias *); | ||||
static int InitPacketAliasLog(struct libalias *); | static int InitPacketAliasLog(struct libalias *); | ||||
static void UninitPacketAliasLog(struct libalias *); | static void UninitPacketAliasLog(struct libalias *); | ||||
void SctpShowAliasStats(struct libalias *la); | void SctpShowAliasStats(struct libalias *la); | ||||
static u_int | #define INGUARD \ | ||||
StartPointIn(struct in_addr alias_addr, | if (grp->alias_port != alias_port || \ | ||||
u_short alias_port, | grp->link_type != link_type || \ | ||||
int link_type) | grp->alias_addr.s_addr != alias_addr.s_addr) \ | ||||
continue; | |||||
static struct group_in * | |||||
StartPointIn(struct libalias *la, | |||||
struct in_addr alias_addr, u_short alias_port, int link_type, | |||||
int create) | |||||
{ | { | ||||
u_int n; | u_int n; | ||||
struct group_in *grp, *tmp; | |||||
n = alias_addr.s_addr; | n = alias_addr.s_addr; | ||||
if (link_type != LINK_PPTP) | |||||
n += alias_port; | n += alias_port; | ||||
n += link_type; | n += link_type; | ||||
return (n % LINK_TABLE_IN_SIZE); | n %= LINK_TABLE_IN_SIZE; | ||||
LIST_FOREACH_SAFE(grp, &la->groupTableIn[n], group_in, tmp) { | |||||
/* Auto cleanup */ | |||||
if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) { | |||||
LIST_REMOVE(grp, group_in); | |||||
free(grp); | |||||
} else { | |||||
INGUARD; | |||||
return (grp); | |||||
} | } | ||||
} | |||||
if (!create || (grp = malloc(sizeof(*grp))) == NULL) | |||||
return (grp); | |||||
grp->alias_addr = alias_addr; | |||||
grp->alias_port = alias_port; | |||||
grp->link_type = link_type; | |||||
LIST_INIT(&grp->full); | |||||
LIST_INIT(&grp->partial); | |||||
LIST_INSERT_HEAD(&la->groupTableIn[n], grp, group_in); | |||||
return (grp); | |||||
} | |||||
#undef INGUARD | |||||
static u_int | static u_int | ||||
StartPointOut(struct in_addr src_addr, struct in_addr dst_addr, | StartPointOut(struct in_addr src_addr, struct in_addr dst_addr, | ||||
u_short src_port, u_short dst_port, int link_type) | u_short src_port, u_short dst_port, int link_type) | ||||
{ | { | ||||
u_int n; | u_int n; | ||||
n = src_addr.s_addr; | n = src_addr.s_addr; | ||||
n += dst_addr.s_addr; | n += dst_addr.s_addr; | ||||
if (link_type != LINK_PPTP) { | |||||
n += src_port; | n += src_port; | ||||
n += dst_port; | n += dst_port; | ||||
} | |||||
n += link_type; | n += link_type; | ||||
return (n % LINK_TABLE_OUT_SIZE); | return (n % LINK_TABLE_OUT_SIZE); | ||||
} | } | ||||
static int | static int | ||||
SeqDiff(u_long x, u_long y) | SeqDiff(u_long x, u_long y) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
/* Local prototypes */ | /* Local prototypes */ | ||||
static int GetNewPort(struct libalias *, struct alias_link *, int); | static int GetNewPort(struct libalias *, struct alias_link *, int); | ||||
#ifndef NO_USE_SOCKETS | #ifndef NO_USE_SOCKETS | ||||
static u_short GetSocket(struct libalias *, u_short, int *, int); | static u_short GetSocket(struct libalias *, u_short, int *, int); | ||||
#endif | #endif | ||||
static void CleanupAliasData(struct libalias *); | static void CleanupAliasData(struct libalias *); | ||||
static void CleanupLink(struct libalias *, struct alias_link **); | static void CleanupLink(struct libalias *, struct alias_link **); | ||||
static void DeleteLink(struct alias_link **); | static void DeleteLink(struct alias_link **); | ||||
static struct alias_link * | |||||
UseLink(struct libalias *, struct alias_link *); | |||||
static struct alias_link * | static struct alias_link * | ||||
ReLink(struct alias_link *, | ReLink(struct alias_link *, | ||||
struct in_addr, struct in_addr, struct in_addr, | struct in_addr, struct in_addr, struct in_addr, | ||||
u_short, u_short, int, int); | u_short, u_short, int, int); | ||||
static struct alias_link * | static struct alias_link * | ||||
FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int); | FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int); | ||||
static struct alias_link * | static struct alias_link * | ||||
FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int); | FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int); | ||||
#define ALIAS_PORT_BASE 0x08000 | static u_short _RandomPort(struct libalias *la); | ||||
#define ALIAS_PORT_MASK 0x07fff | |||||
#define ALIAS_PORT_MASK_EVEN 0x07ffe | |||||
#define GET_NEW_PORT_MAX_ATTEMPTS 20 | #define GET_NEW_PORT_MAX_ATTEMPTS 20 | ||||
#define FIND_EVEN_ALIAS_BASE 1 | /* get random port in network byte order */ | ||||
static u_short | |||||
_RandomPort(struct libalias *la) { | |||||
u_short port; | |||||
port = la->aliasPortLower + | |||||
(arc4random() % la->aliasPortLength); | |||||
return ntohs(port); | |||||
} | |||||
/* GetNewPort() allocates port numbers. Note that if a port number | /* GetNewPort() allocates port numbers. Note that if a port number | ||||
is already in use, that does not mean that it cannot be used by | is already in use, that does not mean that it cannot be used by | ||||
another link concurrently. This is because GetNewPort() looks for | another link concurrently. This is because GetNewPort() looks for | ||||
unused triplets: (dest addr, dest port, alias port). */ | unused triplets: (dest addr, dest port, alias port). */ | ||||
static int | static int | ||||
GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) | GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) | ||||
{ | { | ||||
int i; | int i; | ||||
int max_trials; | int max_trials; | ||||
u_short port_sys; | u_short port; | ||||
u_short port_net; | |||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
/* | /* | ||||
* Description of alias_port_param for GetNewPort(). When | * Description of alias_port_param for GetNewPort(). When | ||||
* this parameter is zero or positive, it precisely specifies | * this parameter is zero or positive, it precisely specifies | ||||
* the port number. GetNewPort() will return this number | * the port number. GetNewPort() will return this number | ||||
* without check that it is in use. | * without check that it is in use. | ||||
* | |||||
* The aliasing port is automatically selected by one of | |||||
* two methods below: | |||||
* | |||||
* When this parameter is GET_ALIAS_PORT, it indicates to get | * When this parameter is GET_ALIAS_PORT, it indicates to get | ||||
* a randomly selected port number. | * a randomly selected port number. | ||||
*/ | */ | ||||
if (alias_port_param == GET_ALIAS_PORT) { | if (alias_port_param >= 0 && alias_port_param < 0x10000) { | ||||
/* | |||||
* The aliasing port is automatically selected by one of | |||||
* two methods below: | |||||
*/ | |||||
max_trials = GET_NEW_PORT_MAX_ATTEMPTS; | |||||
if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { | |||||
/* | |||||
* When the PKT_ALIAS_SAME_PORTS option is chosen, | |||||
* the first try will be the actual source port. If | |||||
* this is already in use, the remainder of the | |||||
* trials will be random. | |||||
*/ | |||||
port_net = lnk->src_port; | |||||
port_sys = ntohs(port_net); | |||||
} else if (la->aliasPortLower) { | |||||
/* First trial is a random port in the aliasing range. */ | |||||
port_sys = la->aliasPortLower + | |||||
(arc4random() % la->aliasPortLength); | |||||
port_net = htons(port_sys); | |||||
} else { | |||||
/* First trial and all subsequent are random. */ | |||||
port_sys = arc4random() & ALIAS_PORT_MASK; | |||||
port_sys += ALIAS_PORT_BASE; | |||||
port_net = htons(port_sys); | |||||
} | |||||
} else if (alias_port_param >= 0 && alias_port_param < 0x10000) { | |||||
lnk->alias_port = (u_short) alias_port_param; | lnk->alias_port = (u_short) alias_port_param; | ||||
return (0); | return (0); | ||||
} else { | } | ||||
if (alias_port_param != GET_ALIAS_PORT) { | |||||
#ifdef LIBALIAS_DEBUG | #ifdef LIBALIAS_DEBUG | ||||
fprintf(stderr, "PacketAlias/GetNewPort(): "); | fprintf(stderr, "PacketAlias/GetNewPort(): "); | ||||
fprintf(stderr, "input parameter error\n"); | fprintf(stderr, "input parameter error\n"); | ||||
#endif | #endif | ||||
return (-1); | return (-1); | ||||
} | } | ||||
max_trials = GET_NEW_PORT_MAX_ATTEMPTS; | |||||
/* | |||||
* When the PKT_ALIAS_SAME_PORTS option is chosen, | |||||
* the first try will be the actual source port. If | |||||
* this is already in use, the remainder of the | |||||
* trials will be random. | |||||
*/ | |||||
port = (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) | |||||
? lnk->src_port | |||||
: _RandomPort(la); | |||||
/* Port number search */ | /* Port number search */ | ||||
for (i = 0; i < max_trials; i++) { | for (i = 0; i < max_trials; i++, port = _RandomPort(la)) { | ||||
int go_ahead; | struct group_in *grp; | ||||
struct alias_link *search_result; | struct alias_link *search_result; | ||||
search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr, | grp = StartPointIn(la, lnk->alias_addr, port, lnk->link_type, 0); | ||||
lnk->dst_port, port_net, | if (grp == NULL) | ||||
lnk->link_type, 0); | break; | ||||
LIST_FOREACH(search_result, &grp->full, all.in) { | |||||
if (lnk->dst_addr.s_addr == search_result->dst_addr.s_addr && | |||||
lnk->dst_port == search_result->dst_port) | |||||
break; /* found match */ | |||||
} | |||||
if (search_result == NULL) | if (search_result == NULL) | ||||
go_ahead = 1; | break; | ||||
else if (!(lnk->flags & LINK_PARTIALLY_SPECIFIED) | |||||
&& (search_result->flags & LINK_PARTIALLY_SPECIFIED)) | |||||
go_ahead = 1; | |||||
else | |||||
go_ahead = 0; | |||||
if (go_ahead) { | |||||
#ifndef NO_USE_SOCKETS | |||||
if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS) | |||||
&& (lnk->flags & LINK_PARTIALLY_SPECIFIED) | |||||
&& ((lnk->link_type == LINK_TCP) || | |||||
(lnk->link_type == LINK_UDP))) { | |||||
if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) { | |||||
lnk->alias_port = port_net; | |||||
return (0); | |||||
} | } | ||||
} else { | |||||
#endif | |||||
lnk->alias_port = port_net; | |||||
return (0); | |||||
#ifndef NO_USE_SOCKETS | |||||
} | |||||
#endif | |||||
} | |||||
if (la->aliasPortLower) { | |||||
port_sys = la->aliasPortLower + | |||||
(arc4random() % la->aliasPortLength); | |||||
port_net = htons(port_sys); | |||||
} else { | |||||
port_sys = arc4random() & ALIAS_PORT_MASK; | |||||
port_sys += ALIAS_PORT_BASE; | |||||
port_net = htons(port_sys); | |||||
} | |||||
} | |||||
if (i >= max_trials) { | |||||
#ifdef LIBALIAS_DEBUG | #ifdef LIBALIAS_DEBUG | ||||
fprintf(stderr, "PacketAlias/GetNewPort(): "); | fprintf(stderr, "PacketAlias/GetNewPort(): "); | ||||
fprintf(stderr, "could not find free port\n"); | fprintf(stderr, "could not find free port\n"); | ||||
#endif | #endif | ||||
return (-1); | |||||
} | |||||
#ifndef NO_USE_SOCKETS | |||||
if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS) && | |||||
(lnk->flags & LINK_PARTIALLY_SPECIFIED) && | |||||
((lnk->link_type == LINK_TCP) || | |||||
(lnk->link_type == LINK_UDP))) { | |||||
if (!GetSocket(la, port, &lnk->sockfd, lnk->link_type)) { | |||||
return (-1); | return (-1); | ||||
} | } | ||||
} | |||||
#endif | |||||
lnk->alias_port = port; | |||||
return (0); | |||||
} | |||||
#ifndef NO_USE_SOCKETS | #ifndef NO_USE_SOCKETS | ||||
static u_short | static u_short | ||||
GetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type) | GetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type) | ||||
{ | { | ||||
int err; | int err; | ||||
int sock; | int sock; | ||||
struct sockaddr_in sock_addr; | struct sockaddr_in sock_addr; | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | FindNewPortGroup(struct libalias *la, | ||||
u_short src_port, | u_short src_port, | ||||
u_short dst_port, | u_short dst_port, | ||||
u_short port_count, | u_short port_count, | ||||
u_char proto, | u_char proto, | ||||
u_char align) | u_char align) | ||||
{ | { | ||||
int i, j; | int i, j; | ||||
int max_trials; | int max_trials; | ||||
u_short port_sys; | u_short port; | ||||
int link_type; | int link_type; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
/* | /* | ||||
* Get link_type from protocol | * Get link_type from protocol | ||||
*/ | */ | ||||
switch (proto) { | switch (proto) { | ||||
Show All 15 Lines | FindNewPortGroup(struct libalias *la, | ||||
max_trials = GET_NEW_PORT_MAX_ATTEMPTS; | max_trials = GET_NEW_PORT_MAX_ATTEMPTS; | ||||
if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { | if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { | ||||
/* | /* | ||||
* When the ALIAS_SAME_PORTS option is chosen, the first | * When the ALIAS_SAME_PORTS option is chosen, the first | ||||
* try will be the actual source port. If this is already | * try will be the actual source port. If this is already | ||||
* in use, the remainder of the trials will be random. | * in use, the remainder of the trials will be random. | ||||
*/ | */ | ||||
port_sys = ntohs(src_port); | port = src_port; | ||||
} else { | } else { | ||||
/* First trial and all subsequent are random. */ | port = _RandomPort(la); | ||||
if (align == FIND_EVEN_ALIAS_BASE) | |||||
port_sys = arc4random() & ALIAS_PORT_MASK_EVEN; | |||||
else | |||||
port_sys = arc4random() & ALIAS_PORT_MASK; | |||||
port_sys += ALIAS_PORT_BASE; | |||||
} | } | ||||
/* Port number search */ | /* Port number search */ | ||||
for (i = 0; i < max_trials; i++) { | for (i = 0; i < max_trials; i++, port = _RandomPort(la)) { | ||||
struct alias_link *search_result; | struct alias_link *search_result; | ||||
for (j = 0; j < port_count; j++) | if (align) | ||||
port &= htons(0xfffe); | |||||
for (j = 0; j < port_count; j++) { | |||||
u_short port_j = ntohs(port) + j; | |||||
if ((search_result = FindLinkIn(la, dst_addr, | if ((search_result = FindLinkIn(la, dst_addr, | ||||
alias_addr, dst_port, htons(port_sys + j), | alias_addr, dst_port, htons(port_j), | ||||
link_type, 0)) != NULL) | link_type, 0)) != NULL) | ||||
break; | break; | ||||
} | |||||
/* Found a good range, return base */ | /* Found a good range, return base */ | ||||
if (j == port_count) | if (j == port_count) | ||||
return (htons(port_sys)); | return (port); | ||||
/* Find a new base to try */ | |||||
if (align == FIND_EVEN_ALIAS_BASE) | |||||
port_sys = arc4random() & ALIAS_PORT_MASK_EVEN; | |||||
else | |||||
port_sys = arc4random() & ALIAS_PORT_MASK; | |||||
port_sys += ALIAS_PORT_BASE; | |||||
} | } | ||||
#ifdef LIBALIAS_DEBUG | #ifdef LIBALIAS_DEBUG | ||||
fprintf(stderr, "PacketAlias/FindNewPortGroup(): "); | fprintf(stderr, "PacketAlias/FindNewPortGroup(): "); | ||||
fprintf(stderr, "could not find free port(s)\n"); | fprintf(stderr, "could not find free port(s)\n"); | ||||
#endif | #endif | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
CleanupAliasData(struct libalias *la) | CleanupAliasData(struct libalias *la) | ||||
{ | { | ||||
struct alias_link *lnk, *lnk_tmp; | struct alias_link *lnk, *lnk_tmp; | ||||
u_int i; | |||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
/* permanent entries may stay */ | /* permanent entries may stay */ | ||||
TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, list_expire, lnk_tmp) | TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, expire.list, lnk_tmp) | ||||
DeleteLink(&lnk); | DeleteLink(&lnk); | ||||
for (i = 0; i < LINK_TABLE_IN_SIZE; i++) { | |||||
struct group_in *grp, *grp_tmp; | |||||
LIST_FOREACH_SAFE(grp, &la->groupTableIn[i], group_in, grp_tmp) | |||||
if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) { | |||||
LIST_REMOVE(grp, group_in); | |||||
free(grp); | |||||
} | } | ||||
} | |||||
} | |||||
static void | static void | ||||
CleanupLink(struct libalias *la, struct alias_link **lnk) | CleanupLink(struct libalias *la, struct alias_link **lnk) | ||||
{ | { | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
if (lnk == NULL || *lnk == NULL) | if (lnk == NULL || *lnk == NULL) | ||||
return; | return; | ||||
if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire_time) { | if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire.timeout) { | ||||
DeleteLink(lnk); | DeleteLink(lnk); | ||||
if ((*lnk) == NULL) | if ((*lnk) == NULL) | ||||
return; | return; | ||||
} | } | ||||
/* move to end, swap may fail on a single entry list */ | /* move to end, swap may fail on a single entry list */ | ||||
TAILQ_REMOVE(&la->checkExpire, (*lnk), list_expire); | TAILQ_REMOVE(&la->checkExpire, (*lnk), expire.list); | ||||
TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), list_expire); | TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), expire.list); | ||||
} | } | ||||
static struct alias_link * | |||||
UseLink(struct libalias *la, struct alias_link *lnk) | |||||
{ | |||||
CleanupLink(la, &lnk); | |||||
if (lnk != NULL) | |||||
lnk->timestamp = LibAliasTime; | |||||
return (lnk); | |||||
} | |||||
static void | static void | ||||
DeleteLink(struct alias_link **plnk) | DeleteLink(struct alias_link **plnk) | ||||
{ | { | ||||
struct alias_link *lnk = *plnk; | struct alias_link *lnk = *plnk; | ||||
struct libalias *la = lnk->la; | struct libalias *la = lnk->la; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
/* Don't do anything if the link is marked permanent */ | /* Don't do anything if the link is marked permanent */ | ||||
if (la->deleteAllLinks == 0 && lnk->flags & LINK_PERMANENT) | if (la->deleteAllLinks == 0 && lnk->flags & LINK_PERMANENT) | ||||
return; | return; | ||||
#ifndef NO_FW_PUNCH | #ifndef NO_FW_PUNCH | ||||
/* Delete associated firewall hole, if any */ | /* Delete associated firewall hole, if any */ | ||||
ClearFWHole(lnk); | ClearFWHole(lnk); | ||||
#endif | #endif | ||||
switch (lnk->link_type) { | |||||
case LINK_PPTP: | |||||
LIST_REMOVE(lnk, pptp.list); | |||||
break; | |||||
default: | |||||
/* Free memory allocated for LSNAT server pool */ | /* Free memory allocated for LSNAT server pool */ | ||||
if (lnk->server != NULL) { | if (lnk->server != NULL) { | ||||
struct server *head, *curr, *next; | struct server *head, *curr, *next; | ||||
head = curr = lnk->server; | head = curr = lnk->server; | ||||
do { | do { | ||||
next = curr->next; | next = curr->next; | ||||
free(curr); | free(curr); | ||||
} while ((curr = next) != head); | } while ((curr = next) != head); | ||||
} | } else { | ||||
/* Adjust output table pointers */ | /* Adjust output table pointers */ | ||||
LIST_REMOVE(lnk, list_out); | LIST_REMOVE(lnk, all.out); | ||||
} | |||||
/* Adjust input table pointers */ | /* Adjust input table pointers */ | ||||
LIST_REMOVE(lnk, list_in); | LIST_REMOVE(lnk, all.in); | ||||
break; | |||||
} | |||||
/* remove from housekeeping */ | /* remove from housekeeping */ | ||||
TAILQ_REMOVE(&la->checkExpire, lnk, list_expire); | TAILQ_REMOVE(&la->checkExpire, lnk, expire.list); | ||||
#ifndef NO_USE_SOCKETS | #ifndef NO_USE_SOCKETS | ||||
/* Close socket, if one has been allocated */ | /* Close socket, if one has been allocated */ | ||||
if (lnk->sockfd != -1) { | if (lnk->sockfd != -1) { | ||||
la->sockCount--; | la->sockCount--; | ||||
close(lnk->sockfd); | close(lnk->sockfd); | ||||
} | } | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, | AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, | ||||
struct in_addr alias_addr, u_short src_port, u_short dst_port, | struct in_addr alias_addr, u_short src_port, u_short dst_port, | ||||
int alias_port_param, int link_type) | int alias_port_param, int link_type) | ||||
{ | { | ||||
u_int start_point; | u_int start_point; | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
lnk = malloc(sizeof(struct alias_link)); | lnk = malloc(sizeof(struct alias_link)); | ||||
if (lnk != NULL) { | if (lnk == NULL) { | ||||
#ifdef LIBALIAS_DEBUG | |||||
fprintf(stderr, "PacketAlias/AddLink(): "); | |||||
fprintf(stderr, "malloc() call failed.\n"); | |||||
#endif | |||||
return (NULL); | |||||
} | |||||
/* Basic initialization */ | /* Basic initialization */ | ||||
lnk->la = la; | lnk->la = la; | ||||
lnk->src_addr = src_addr; | lnk->src_addr = src_addr; | ||||
lnk->dst_addr = dst_addr; | lnk->dst_addr = dst_addr; | ||||
lnk->alias_addr = alias_addr; | lnk->alias_addr = alias_addr; | ||||
lnk->proxy_addr.s_addr = INADDR_ANY; | lnk->proxy_addr.s_addr = INADDR_ANY; | ||||
lnk->src_port = src_port; | lnk->src_port = src_port; | ||||
lnk->dst_port = dst_port; | lnk->dst_port = dst_port; | ||||
lnk->proxy_port = 0; | lnk->proxy_port = 0; | ||||
lnk->server = NULL; | lnk->server = NULL; | ||||
lnk->link_type = link_type; | lnk->link_type = link_type; | ||||
#ifndef NO_USE_SOCKETS | #ifndef NO_USE_SOCKETS | ||||
lnk->sockfd = -1; | lnk->sockfd = -1; | ||||
#endif | #endif | ||||
lnk->flags = 0; | lnk->flags = 0; | ||||
lnk->pflags = 0; | lnk->pflags = 0; | ||||
lnk->timestamp = LibAliasTime; | lnk->timestamp = LibAliasTime; | ||||
/* Expiration time */ | /* Expiration time */ | ||||
switch (link_type) { | switch (link_type) { | ||||
case LINK_ICMP: | case LINK_ICMP: | ||||
lnk->expire_time = ICMP_EXPIRE_TIME; | lnk->expire.timeout = ICMP_EXPIRE_TIME; | ||||
break; | break; | ||||
case LINK_UDP: | case LINK_UDP: | ||||
lnk->expire_time = UDP_EXPIRE_TIME; | lnk->expire.timeout = UDP_EXPIRE_TIME; | ||||
break; | break; | ||||
case LINK_TCP: | case LINK_TCP: | ||||
lnk->expire_time = TCP_EXPIRE_INITIAL; | lnk->expire.timeout = TCP_EXPIRE_INITIAL; | ||||
break; | break; | ||||
case LINK_PPTP: | |||||
lnk->flags |= LINK_PERMANENT; /* no timeout. */ | |||||
break; | |||||
case LINK_FRAGMENT_ID: | case LINK_FRAGMENT_ID: | ||||
lnk->expire_time = FRAGMENT_ID_EXPIRE_TIME; | lnk->expire.timeout = FRAGMENT_ID_EXPIRE_TIME; | ||||
break; | break; | ||||
case LINK_FRAGMENT_PTR: | case LINK_FRAGMENT_PTR: | ||||
lnk->expire_time = FRAGMENT_PTR_EXPIRE_TIME; | lnk->expire.timeout = FRAGMENT_PTR_EXPIRE_TIME; | ||||
break; | break; | ||||
case LINK_ADDR: | case LINK_ADDR: | ||||
break; | break; | ||||
default: | default: | ||||
lnk->expire_time = PROTO_EXPIRE_TIME; | lnk->expire.timeout = PROTO_EXPIRE_TIME; | ||||
break; | break; | ||||
} | } | ||||
/* Determine alias flags */ | /* Determine alias flags */ | ||||
if (dst_addr.s_addr == INADDR_ANY) | if (dst_addr.s_addr == INADDR_ANY) | ||||
lnk->flags |= LINK_UNKNOWN_DEST_ADDR; | lnk->flags |= LINK_UNKNOWN_DEST_ADDR; | ||||
if (dst_port == 0) | if (dst_port == 0) | ||||
lnk->flags |= LINK_UNKNOWN_DEST_PORT; | lnk->flags |= LINK_UNKNOWN_DEST_PORT; | ||||
/* Determine alias port */ | /* Determine alias port */ | ||||
if (GetNewPort(la, lnk, alias_port_param) != 0) { | if (GetNewPort(la, lnk, alias_port_param) != 0) { | ||||
free(lnk); | free(lnk); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* Link-type dependent initialization */ | /* Link-type dependent initialization */ | ||||
switch (link_type) { | switch (link_type) { | ||||
struct tcp_dat *aux_tcp; | |||||
case LINK_ICMP: | case LINK_ICMP: | ||||
la->icmpLinkCount++; | la->icmpLinkCount++; | ||||
break; | break; | ||||
case LINK_UDP: | case LINK_UDP: | ||||
la->udpLinkCount++; | la->udpLinkCount++; | ||||
break; | break; | ||||
case LINK_TCP: | case LINK_TCP: { | ||||
struct tcp_dat *aux_tcp; | |||||
int i; | |||||
aux_tcp = malloc(sizeof(struct tcp_dat)); | aux_tcp = malloc(sizeof(struct tcp_dat)); | ||||
if (aux_tcp != NULL) { | if (aux_tcp != NULL) { | ||||
int i; | #ifdef LIBALIAS_DEBUG | ||||
fprintf(stderr, "PacketAlias/AddLink: "); | |||||
fprintf(stderr, " cannot allocate auxiliary TCP data\n"); | |||||
#endif | |||||
free(lnk); | |||||
return (NULL); | |||||
} | |||||
la->tcpLinkCount++; | la->tcpLinkCount++; | ||||
aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED; | aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED; | ||||
aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED; | aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED; | ||||
aux_tcp->state.index = 0; | aux_tcp->state.index = 0; | ||||
aux_tcp->state.ack_modified = 0; | aux_tcp->state.ack_modified = 0; | ||||
for (i = 0; i < N_LINK_TCP_DATA; i++) | for (i = 0; i < N_LINK_TCP_DATA; i++) | ||||
aux_tcp->ack[i].active = 0; | aux_tcp->ack[i].active = 0; | ||||
aux_tcp->fwhole = -1; | aux_tcp->fwhole = -1; | ||||
lnk->data.tcp = aux_tcp; | lnk->data.tcp = aux_tcp; | ||||
} else { | |||||
#ifdef LIBALIAS_DEBUG | |||||
fprintf(stderr, "PacketAlias/AddLink: "); | |||||
fprintf(stderr, " cannot allocate auxiliary TCP data\n"); | |||||
#endif | |||||
free(lnk); | |||||
return (NULL); | |||||
} | } | ||||
break; | break; | ||||
case LINK_PPTP: | case LINK_PPTP: | ||||
la->pptpLinkCount++; | la->pptpLinkCount++; | ||||
break; | break; | ||||
case LINK_FRAGMENT_ID: | case LINK_FRAGMENT_ID: | ||||
la->fragmentIdLinkCount++; | la->fragmentIdLinkCount++; | ||||
break; | break; | ||||
case LINK_FRAGMENT_PTR: | case LINK_FRAGMENT_PTR: | ||||
la->fragmentPtrLinkCount++; | la->fragmentPtrLinkCount++; | ||||
break; | break; | ||||
case LINK_ADDR: | case LINK_ADDR: | ||||
break; | break; | ||||
default: | default: | ||||
la->protoLinkCount++; | la->protoLinkCount++; | ||||
break; | break; | ||||
} | } | ||||
switch (link_type) { | |||||
case LINK_PPTP: | |||||
LIST_INSERT_HEAD(&la->pptpList, lnk, pptp.list); | |||||
break; | |||||
default: { | |||||
struct group_in *grp; | |||||
grp = StartPointIn(la, alias_addr, lnk->alias_port, link_type, 1); | |||||
if (grp == NULL) { | |||||
free(lnk); | |||||
return (NULL); | |||||
} | |||||
/* Set up pointers for output lookup table */ | /* Set up pointers for output lookup table */ | ||||
start_point = StartPointOut(src_addr, dst_addr, | start_point = StartPointOut(src_addr, dst_addr, | ||||
src_port, dst_port, link_type); | src_port, dst_port, link_type); | ||||
LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, list_out); | LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, all.out); | ||||
/* Set up pointers for input lookup table */ | /* Set up pointers for input lookup table */ | ||||
start_point = StartPointIn(alias_addr, lnk->alias_port, link_type); | if (lnk->flags & LINK_PARTIALLY_SPECIFIED) | ||||
LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in); | LIST_INSERT_HEAD(&grp->partial, lnk, all.in); | ||||
else | |||||
LIST_INSERT_HEAD(&grp->full, lnk, all.in); | |||||
} | |||||
break; | |||||
} | |||||
/* Include the element into the housekeeping list */ | /* Include the element into the housekeeping list */ | ||||
TAILQ_INSERT_TAIL(&la->checkExpire, lnk, list_expire); | TAILQ_INSERT_TAIL(&la->checkExpire, lnk, expire.list); | ||||
} else { | |||||
#ifdef LIBALIAS_DEBUG | if (la->packetAliasMode & PKT_ALIAS_LOG) | ||||
fprintf(stderr, "PacketAlias/AddLink(): "); | |||||
fprintf(stderr, "malloc() call failed.\n"); | |||||
#endif | |||||
} | |||||
if (la->packetAliasMode & PKT_ALIAS_LOG) { | |||||
ShowAliasStats(la); | ShowAliasStats(la); | ||||
} | |||||
return (lnk); | return (lnk); | ||||
} | } | ||||
/* | /* | ||||
* If alias_port_param is less than zero, alias port will be automatically | * If alias_port_param is less than zero, alias port will be automatically | ||||
* chosen. If greater than zero, equal to alias port | * chosen. If greater than zero, equal to alias port | ||||
*/ | */ | ||||
static struct alias_link * | static struct alias_link * | ||||
Show All 19 Lines | if (new_lnk != NULL && | ||||
old_lnk->data.tcp->fwhole > 0) { | old_lnk->data.tcp->fwhole > 0) { | ||||
PunchFWHole(new_lnk); | PunchFWHole(new_lnk); | ||||
} | } | ||||
#endif | #endif | ||||
DeleteLink(&old_lnk); | DeleteLink(&old_lnk); | ||||
return (new_lnk); | return (new_lnk); | ||||
} | } | ||||
#define OUTGUARD \ | |||||
if (lnk->src_port != src_port || \ | |||||
lnk->src_addr.s_addr != src_addr.s_addr || \ | |||||
lnk->dst_addr.s_addr != dst_addr.s_addr || \ | |||||
lnk->dst_port != dst_port || \ | |||||
lnk->link_type != link_type) \ | |||||
continue; | |||||
static struct alias_link * | static struct alias_link * | ||||
_SearchLinkOut(struct libalias *la, struct in_addr src_addr, | |||||
struct in_addr dst_addr, | |||||
u_short src_port, | |||||
u_short dst_port, | |||||
int link_type) { | |||||
u_int i; | |||||
struct alias_link *lnk; | |||||
i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type); | |||||
LIST_FOREACH(lnk, &la->linkTableOut[i], all.out) { | |||||
OUTGUARD; | |||||
return (UseLink(la, lnk)); | |||||
} | |||||
return (NULL); | |||||
} | |||||
#undef OUTGUARD | |||||
static struct alias_link * | |||||
_FindLinkOut(struct libalias *la, struct in_addr src_addr, | _FindLinkOut(struct libalias *la, struct in_addr src_addr, | ||||
struct in_addr dst_addr, | struct in_addr dst_addr, | ||||
u_short src_port, | u_short src_port, | ||||
u_short dst_port, | u_short dst_port, | ||||
int link_type, | int link_type, | ||||
int replace_partial_links) | int replace_partial_links) | ||||
{ | { | ||||
u_int i; | |||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type); | lnk = _SearchLinkOut(la, src_addr, dst_addr, src_port, dst_port, link_type); | ||||
LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) { | if (lnk != NULL || !replace_partial_links) | ||||
if (lnk->dst_addr.s_addr == dst_addr.s_addr && | return (lnk); | ||||
lnk->src_addr.s_addr == src_addr.s_addr && | |||||
lnk->src_port == src_port && | |||||
lnk->dst_port == dst_port && | |||||
lnk->link_type == link_type && | |||||
lnk->server == NULL) | |||||
break; | |||||
} | |||||
CleanupLink(la, &lnk); | |||||
if (lnk != NULL) | |||||
lnk->timestamp = LibAliasTime; | |||||
/* Search for partially specified links. */ | /* Search for partially specified links. */ | ||||
if (lnk == NULL && replace_partial_links) { | |||||
if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) { | if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) { | ||||
lnk = _FindLinkOut(la, src_addr, dst_addr, src_port, 0, | lnk = _SearchLinkOut(la, src_addr, dst_addr, src_port, 0, | ||||
link_type, 0); | link_type); | ||||
if (lnk == NULL) | if (lnk == NULL) | ||||
lnk = _FindLinkOut(la, src_addr, NO_ADDR, src_port, | lnk = _SearchLinkOut(la, src_addr, ANY_ADDR, src_port, | ||||
dst_port, link_type, 0); | dst_port, link_type); | ||||
} | } | ||||
if (lnk == NULL && | if (lnk == NULL && | ||||
(dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) { | (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) { | ||||
lnk = _FindLinkOut(la, src_addr, NO_ADDR, src_port, 0, | lnk = _SearchLinkOut(la, src_addr, ANY_ADDR, src_port, 0, | ||||
link_type, 0); | link_type); | ||||
} | } | ||||
if (lnk != NULL) { | if (lnk != NULL) { | ||||
lnk = ReLink(lnk, | lnk = ReLink(lnk, | ||||
src_addr, dst_addr, lnk->alias_addr, | src_addr, dst_addr, lnk->alias_addr, | ||||
src_port, dst_port, lnk->alias_port, | src_port, dst_port, lnk->alias_port, | ||||
link_type); | link_type); | ||||
} | } | ||||
} | |||||
return (lnk); | return (lnk); | ||||
} | } | ||||
static struct alias_link * | static struct alias_link * | ||||
FindLinkOut(struct libalias *la, struct in_addr src_addr, | FindLinkOut(struct libalias *la, struct in_addr src_addr, | ||||
struct in_addr dst_addr, | struct in_addr dst_addr, | ||||
u_short src_port, | u_short src_port, | ||||
u_short dst_port, | u_short dst_port, | ||||
Show All 10 Lines | if (lnk == NULL) { | ||||
/* | /* | ||||
* The following allows permanent links to be specified as | * The following allows permanent links to be specified as | ||||
* using the default source address (i.e. device interface | * using the default source address (i.e. device interface | ||||
* address) without knowing in advance what that address | * address) without knowing in advance what that address | ||||
* is. | * is. | ||||
*/ | */ | ||||
if (la->aliasAddress.s_addr != INADDR_ANY && | if (la->aliasAddress.s_addr != INADDR_ANY && | ||||
src_addr.s_addr == la->aliasAddress.s_addr) { | src_addr.s_addr == la->aliasAddress.s_addr) { | ||||
lnk = _FindLinkOut(la, NO_ADDR, dst_addr, src_port, dst_port, | lnk = _FindLinkOut(la, ANY_ADDR, dst_addr, src_port, dst_port, | ||||
link_type, replace_partial_links); | link_type, replace_partial_links); | ||||
} | } | ||||
} | } | ||||
return (lnk); | return (lnk); | ||||
} | } | ||||
static struct alias_link * | static struct alias_link * | ||||
_FindLinkIn(struct libalias *la, struct in_addr dst_addr, | _FindLinkIn(struct libalias *la, struct in_addr dst_addr, | ||||
struct in_addr alias_addr, | struct in_addr alias_addr, | ||||
u_short dst_port, | u_short dst_port, | ||||
u_short alias_port, | u_short alias_port, | ||||
int link_type, | int link_type, | ||||
int replace_partial_links) | int replace_partial_links) | ||||
{ | { | ||||
int flags_in; | int flags_in; | ||||
u_int start_point; | struct group_in *grp; | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
struct alias_link *lnk_fully_specified; | |||||
struct alias_link *lnk_unknown_all; | struct alias_link *lnk_unknown_all; | ||||
struct alias_link *lnk_unknown_dst_addr; | struct alias_link *lnk_unknown_dst_addr; | ||||
struct alias_link *lnk_unknown_dst_port; | struct alias_link *lnk_unknown_dst_port; | ||||
struct in_addr src_addr; | |||||
u_short src_port; | |||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
/* Initialize pointers */ | /* Initialize pointers */ | ||||
lnk_fully_specified = NULL; | |||||
lnk_unknown_all = NULL; | lnk_unknown_all = NULL; | ||||
lnk_unknown_dst_addr = NULL; | lnk_unknown_dst_addr = NULL; | ||||
lnk_unknown_dst_port = NULL; | lnk_unknown_dst_port = NULL; | ||||
/* If either the dest addr or port is unknown, the search | /* If either the dest addr or port is unknown, the search | ||||
* loop will have to know about this. */ | * loop will have to know about this. */ | ||||
flags_in = 0; | flags_in = 0; | ||||
if (dst_addr.s_addr == INADDR_ANY) | if (dst_addr.s_addr == INADDR_ANY) | ||||
flags_in |= LINK_UNKNOWN_DEST_ADDR; | flags_in |= LINK_UNKNOWN_DEST_ADDR; | ||||
if (dst_port == 0) | if (dst_port == 0) | ||||
flags_in |= LINK_UNKNOWN_DEST_PORT; | flags_in |= LINK_UNKNOWN_DEST_PORT; | ||||
/* Search loop */ | /* Search loop */ | ||||
start_point = StartPointIn(alias_addr, alias_port, link_type); | grp = StartPointIn(la, alias_addr, alias_port, link_type, 0); | ||||
LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) { | if (grp == NULL) | ||||
int flags; | return (NULL); | ||||
flags = flags_in | lnk->flags; | switch (flags_in) { | ||||
if (!(flags & LINK_PARTIALLY_SPECIFIED)) { | case 0: | ||||
if (lnk->alias_addr.s_addr == alias_addr.s_addr | LIST_FOREACH(lnk, &grp->full, all.in) { | ||||
&& lnk->alias_port == alias_port | if (lnk->dst_addr.s_addr == dst_addr.s_addr && | ||||
&& lnk->dst_addr.s_addr == dst_addr.s_addr | lnk->dst_port == dst_port) | ||||
&& lnk->dst_port == dst_port | return (UseLink(la, lnk)); | ||||
&& lnk->link_type == link_type) { | } | ||||
lnk_fully_specified = lnk; | |||||
break; | break; | ||||
case LINK_UNKNOWN_DEST_PORT: | |||||
LIST_FOREACH(lnk, &grp->full, all.in) { | |||||
if(lnk->dst_addr.s_addr == dst_addr.s_addr) { | |||||
lnk_unknown_dst_port = lnk; | |||||
break; | |||||
} | } | ||||
} else if ((flags & LINK_UNKNOWN_DEST_ADDR) | |||||
&& (flags & LINK_UNKNOWN_DEST_PORT)) { | |||||
if (lnk->alias_addr.s_addr == alias_addr.s_addr | |||||
&& lnk->alias_port == alias_port | |||||
&& lnk->link_type == link_type) { | |||||
if (lnk_unknown_all == NULL) | |||||
lnk_unknown_all = lnk; | |||||
} | } | ||||
} else if (flags & LINK_UNKNOWN_DEST_ADDR) { | break; | ||||
if (lnk->alias_addr.s_addr == alias_addr.s_addr | case LINK_UNKNOWN_DEST_ADDR: | ||||
&& lnk->alias_port == alias_port | LIST_FOREACH(lnk, &grp->full, all.in) { | ||||
&& lnk->link_type == link_type | if(lnk->dst_port == dst_port) { | ||||
&& lnk->dst_port == dst_port) { | |||||
if (lnk_unknown_dst_addr == NULL) | |||||
lnk_unknown_dst_addr = lnk; | lnk_unknown_dst_addr = lnk; | ||||
break; | |||||
} | } | ||||
} else if (flags & LINK_UNKNOWN_DEST_PORT) { | } | ||||
if (lnk->alias_addr.s_addr == alias_addr.s_addr | break; | ||||
&& lnk->alias_port == alias_port | case LINK_PARTIALLY_SPECIFIED: | ||||
&& lnk->link_type == link_type | lnk_unknown_all = LIST_FIRST(&grp->full); | ||||
&& lnk->dst_addr.s_addr == dst_addr.s_addr) { | break; | ||||
if (lnk_unknown_dst_port == NULL) | } | ||||
if (lnk_unknown_dst_port == NULL) { | |||||
LIST_FOREACH(lnk, &grp->partial, all.in) { | |||||
int flags = (flags_in | lnk->flags) & LINK_PARTIALLY_SPECIFIED; | |||||
if (flags == LINK_PARTIALLY_SPECIFIED && | |||||
lnk_unknown_all == NULL) | |||||
lnk_unknown_all = lnk; | |||||
if (flags == LINK_UNKNOWN_DEST_ADDR && | |||||
lnk->dst_port == dst_port && | |||||
lnk_unknown_dst_addr == NULL) | |||||
lnk_unknown_dst_addr = lnk; | |||||
if (flags == LINK_UNKNOWN_DEST_PORT && | |||||
lnk->dst_addr.s_addr == dst_addr.s_addr) { | |||||
lnk_unknown_dst_port = lnk; | lnk_unknown_dst_port = lnk; | ||||
break; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
CleanupLink(la, &lnk_fully_specified); | lnk = (lnk_unknown_dst_port != NULL) ? lnk_unknown_dst_port | ||||
if (lnk_fully_specified != NULL) { | : (lnk_unknown_dst_addr != NULL) ? lnk_unknown_dst_addr | ||||
lnk_fully_specified->timestamp = LibAliasTime; | : lnk_unknown_all; | ||||
lnk = lnk_fully_specified; | |||||
} else if (lnk_unknown_dst_port != NULL) | |||||
lnk = lnk_unknown_dst_port; | |||||
else if (lnk_unknown_dst_addr != NULL) | |||||
lnk = lnk_unknown_dst_addr; | |||||
else if (lnk_unknown_all != NULL) | |||||
lnk = lnk_unknown_all; | |||||
else | |||||
return (NULL); | |||||
if (replace_partial_links && | if (lnk == NULL || !replace_partial_links) | ||||
(lnk->flags & LINK_PARTIALLY_SPECIFIED || lnk->server != NULL)) { | return (lnk); | ||||
struct in_addr src_addr; | |||||
u_short src_port; | |||||
if (lnk->server != NULL) { /* LSNAT link */ | if (lnk->server != NULL) { /* LSNAT link */ | ||||
src_addr = lnk->server->addr; | src_addr = lnk->server->addr; | ||||
src_port = lnk->server->port; | src_port = lnk->server->port; | ||||
lnk->server = lnk->server->next; | lnk->server = lnk->server->next; | ||||
} else { | } else { | ||||
src_addr = lnk->src_addr; | src_addr = lnk->src_addr; | ||||
src_port = lnk->src_port; | src_port = lnk->src_port; | ||||
} | } | ||||
if (link_type == LINK_SCTP) { | if (link_type == LINK_SCTP) { | ||||
lnk->src_addr = src_addr; | lnk->src_addr = src_addr; | ||||
lnk->src_port = src_port; | lnk->src_port = src_port; | ||||
return (lnk); | } else { | ||||
} | |||||
lnk = ReLink(lnk, | lnk = ReLink(lnk, | ||||
src_addr, dst_addr, alias_addr, | src_addr, dst_addr, alias_addr, | ||||
src_port, dst_port, alias_port, | src_port, dst_port, alias_port, | ||||
link_type); | link_type); | ||||
} | } | ||||
return (lnk); | return (lnk); | ||||
} | } | ||||
Show All 15 Lines | if (lnk == NULL) { | ||||
/* | /* | ||||
* The following allows permanent links to be specified as | * The following allows permanent links to be specified as | ||||
* using the default aliasing address (i.e. device | * using the default aliasing address (i.e. device | ||||
* interface address) without knowing in advance what that | * interface address) without knowing in advance what that | ||||
* address is. | * address is. | ||||
*/ | */ | ||||
if (la->aliasAddress.s_addr != INADDR_ANY && | if (la->aliasAddress.s_addr != INADDR_ANY && | ||||
alias_addr.s_addr == la->aliasAddress.s_addr) { | alias_addr.s_addr == la->aliasAddress.s_addr) { | ||||
lnk = _FindLinkIn(la, dst_addr, NO_ADDR, dst_port, alias_port, | lnk = _FindLinkIn(la, dst_addr, ANY_ADDR, dst_port, alias_port, | ||||
link_type, replace_partial_links); | link_type, replace_partial_links); | ||||
} | } | ||||
} | } | ||||
return (lnk); | return (lnk); | ||||
} | } | ||||
/* External routines for finding/adding links | /* External routines for finding/adding links | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | FindFragmentIn1(struct libalias *la, struct in_addr dst_addr, | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
lnk = FindLinkIn(la, dst_addr, alias_addr, | lnk = FindLinkIn(la, dst_addr, alias_addr, | ||||
NO_DEST_PORT, ip_id, | NO_DEST_PORT, ip_id, | ||||
LINK_FRAGMENT_ID, 0); | LINK_FRAGMENT_ID, 0); | ||||
if (lnk == NULL) { | if (lnk == NULL) { | ||||
lnk = AddLink(la, NO_ADDR, dst_addr, alias_addr, | lnk = AddLink(la, ANY_ADDR, dst_addr, alias_addr, | ||||
NO_SRC_PORT, NO_DEST_PORT, ip_id, | NO_SRC_PORT, NO_DEST_PORT, ip_id, | ||||
LINK_FRAGMENT_ID); | LINK_FRAGMENT_ID); | ||||
} | } | ||||
return (lnk); | return (lnk); | ||||
} | } | ||||
/* Doesn't add a link if one is not found. */ | /* Doesn't add a link if one is not found. */ | ||||
struct alias_link * | struct alias_link * | ||||
FindFragmentIn2(struct libalias *la, struct in_addr dst_addr, | FindFragmentIn2(struct libalias *la, struct in_addr dst_addr, | ||||
struct in_addr alias_addr, u_short ip_id) | struct in_addr alias_addr, u_short ip_id) | ||||
{ | { | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
return FindLinkIn(la, dst_addr, alias_addr, | return FindLinkIn(la, dst_addr, alias_addr, | ||||
NO_DEST_PORT, ip_id, | NO_DEST_PORT, ip_id, | ||||
LINK_FRAGMENT_ID, 0); | LINK_FRAGMENT_ID, 0); | ||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
AddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr, | AddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr, | ||||
u_short ip_id) | u_short ip_id) | ||||
{ | { | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
return AddLink(la, NO_ADDR, dst_addr, NO_ADDR, | return AddLink(la, ANY_ADDR, dst_addr, ANY_ADDR, | ||||
NO_SRC_PORT, NO_DEST_PORT, ip_id, | NO_SRC_PORT, NO_DEST_PORT, ip_id, | ||||
LINK_FRAGMENT_PTR); | LINK_FRAGMENT_PTR); | ||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindFragmentPtr(struct libalias *la, struct in_addr dst_addr, | FindFragmentPtr(struct libalias *la, struct in_addr dst_addr, | ||||
u_short ip_id) | u_short ip_id) | ||||
{ | { | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
return FindLinkIn(la, dst_addr, NO_ADDR, | return FindLinkIn(la, dst_addr, ANY_ADDR, | ||||
NO_DEST_PORT, ip_id, | NO_DEST_PORT, ip_id, | ||||
LINK_FRAGMENT_PTR, 0); | LINK_FRAGMENT_PTR, 0); | ||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindProtoIn(struct libalias *la, struct in_addr dst_addr, | FindProtoIn(struct libalias *la, struct in_addr dst_addr, | ||||
struct in_addr alias_addr, | struct in_addr alias_addr, | ||||
u_char proto) | u_char proto) | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | AddPptp(struct libalias *la, struct in_addr src_addr, | ||||
return (lnk); | return (lnk); | ||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr, | FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr, | ||||
struct in_addr dst_addr, | struct in_addr dst_addr, | ||||
u_int16_t src_call_id) | u_int16_t src_call_id) | ||||
{ | { | ||||
u_int i; | |||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); | LIST_FOREACH(lnk, &la->pptpList, pptp.list) | ||||
LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) | if (lnk->src_addr.s_addr == src_addr.s_addr && | ||||
if (lnk->link_type == LINK_PPTP && | |||||
lnk->src_addr.s_addr == src_addr.s_addr && | |||||
lnk->dst_addr.s_addr == dst_addr.s_addr && | lnk->dst_addr.s_addr == dst_addr.s_addr && | ||||
lnk->src_port == src_call_id) | lnk->src_port == src_call_id) | ||||
break; | break; | ||||
CleanupLink(la, &lnk); | return (UseLink(la, lnk)); | ||||
return (lnk); | |||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr, | FindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr, | ||||
struct in_addr dst_addr, | struct in_addr dst_addr, | ||||
u_int16_t dst_call_id) | u_int16_t dst_call_id) | ||||
{ | { | ||||
u_int i; | |||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); | LIST_FOREACH(lnk, &la->pptpList, pptp.list) | ||||
LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) | if (lnk->src_addr.s_addr == src_addr.s_addr && | ||||
if (lnk->link_type == LINK_PPTP && | |||||
lnk->src_addr.s_addr == src_addr.s_addr && | |||||
lnk->dst_addr.s_addr == dst_addr.s_addr && | lnk->dst_addr.s_addr == dst_addr.s_addr && | ||||
lnk->dst_port == dst_call_id) | lnk->dst_port == dst_call_id) | ||||
break; | break; | ||||
CleanupLink(la, &lnk); | return (UseLink(la, lnk)); | ||||
return (lnk); | |||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindPptpInByCallId(struct libalias *la, struct in_addr dst_addr, | FindPptpInByCallId(struct libalias *la, struct in_addr dst_addr, | ||||
struct in_addr alias_addr, | struct in_addr alias_addr, | ||||
u_int16_t dst_call_id) | u_int16_t dst_call_id) | ||||
{ | { | ||||
u_int i; | |||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
i = StartPointIn(alias_addr, 0, LINK_PPTP); | |||||
LIST_FOREACH(lnk, &la->linkTableIn[i], list_in) | LIST_FOREACH(lnk, &la->pptpList, pptp.list) | ||||
if (lnk->link_type == LINK_PPTP && | if (lnk->dst_port == dst_call_id && | ||||
lnk->dst_addr.s_addr == dst_addr.s_addr && | lnk->dst_addr.s_addr == dst_addr.s_addr && | ||||
lnk->alias_addr.s_addr == alias_addr.s_addr && | lnk->alias_addr.s_addr == alias_addr.s_addr) | ||||
lnk->dst_port == dst_call_id) | |||||
break; | break; | ||||
CleanupLink(la, &lnk); | return (UseLink(la, lnk)); | ||||
return (lnk); | |||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr, | FindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr, | ||||
struct in_addr alias_addr, | struct in_addr alias_addr, | ||||
u_int16_t alias_call_id) | u_int16_t alias_call_id) | ||||
{ | { | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
lnk = FindLinkIn(la, dst_addr, alias_addr, | LIST_FOREACH(lnk, &la->pptpList, pptp.list) | ||||
0 /* any */ , alias_call_id, | if (lnk->alias_port == alias_call_id && | ||||
LINK_PPTP, 0); | lnk->dst_addr.s_addr == dst_addr.s_addr && | ||||
lnk->alias_addr.s_addr == alias_addr.s_addr) | |||||
break; | |||||
return (lnk); | return (lnk); | ||||
} | } | ||||
struct alias_link * | struct alias_link * | ||||
FindRtspOut(struct libalias *la, struct in_addr src_addr, | FindRtspOut(struct libalias *la, struct in_addr src_addr, | ||||
struct in_addr dst_addr, | struct in_addr dst_addr, | ||||
u_short src_port, | u_short src_port, | ||||
Show All 30 Lines | |||||
} | } | ||||
struct in_addr | struct in_addr | ||||
FindOriginalAddress(struct libalias *la, struct in_addr alias_addr) | FindOriginalAddress(struct libalias *la, struct in_addr alias_addr) | ||||
{ | { | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
lnk = FindLinkIn(la, NO_ADDR, alias_addr, | lnk = FindLinkIn(la, ANY_ADDR, alias_addr, | ||||
0, 0, LINK_ADDR, 0); | 0, 0, LINK_ADDR, 0); | ||||
if (lnk == NULL) { | if (lnk == NULL) { | ||||
la->newDefaultLink = 1; | la->newDefaultLink = 1; | ||||
if (la->targetAddress.s_addr == INADDR_ANY) | if (la->targetAddress.s_addr == INADDR_ANY) | ||||
return (alias_addr); | return (alias_addr); | ||||
else if (la->targetAddress.s_addr == INADDR_NONE) | else if (la->targetAddress.s_addr == INADDR_NONE) | ||||
return (la->aliasAddress.s_addr != INADDR_ANY) ? | return (la->aliasAddress.s_addr != INADDR_ANY) ? | ||||
la->aliasAddress : alias_addr; | la->aliasAddress : alias_addr; | ||||
Show All 15 Lines | |||||
} | } | ||||
struct in_addr | struct in_addr | ||||
FindAliasAddress(struct libalias *la, struct in_addr original_addr) | FindAliasAddress(struct libalias *la, struct in_addr original_addr) | ||||
{ | { | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
lnk = FindLinkOut(la, original_addr, NO_ADDR, | lnk = FindLinkOut(la, original_addr, ANY_ADDR, | ||||
0, 0, LINK_ADDR, 0); | 0, 0, LINK_ADDR, 0); | ||||
if (lnk == NULL) { | if (lnk == NULL) { | ||||
return (la->aliasAddress.s_addr != INADDR_ANY) ? | return (la->aliasAddress.s_addr != INADDR_ANY) ? | ||||
la->aliasAddress : original_addr; | la->aliasAddress : original_addr; | ||||
} else { | } else { | ||||
if (lnk->alias_addr.s_addr == INADDR_ANY) | if (lnk->alias_addr.s_addr == INADDR_ANY) | ||||
return (la->aliasAddress.s_addr != INADDR_ANY) ? | return (la->aliasAddress.s_addr != INADDR_ANY) ? | ||||
la->aliasAddress : original_addr; | la->aliasAddress : original_addr; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
SetStateIn(struct alias_link *lnk, int state) | SetStateIn(struct alias_link *lnk, int state) | ||||
{ | { | ||||
/* TCP input state */ | /* TCP input state */ | ||||
switch (state) { | switch (state) { | ||||
case ALIAS_TCP_STATE_DISCONNECTED: | case ALIAS_TCP_STATE_DISCONNECTED: | ||||
if (lnk->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED) | if (lnk->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED) | ||||
lnk->expire_time = TCP_EXPIRE_DEAD; | lnk->expire.timeout = TCP_EXPIRE_DEAD; | ||||
else | else | ||||
lnk->expire_time = TCP_EXPIRE_SINGLEDEAD; | lnk->expire.timeout = TCP_EXPIRE_SINGLEDEAD; | ||||
break; | break; | ||||
case ALIAS_TCP_STATE_CONNECTED: | case ALIAS_TCP_STATE_CONNECTED: | ||||
if (lnk->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED) | if (lnk->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED) | ||||
lnk->expire_time = TCP_EXPIRE_CONNECTED; | lnk->expire.timeout = TCP_EXPIRE_CONNECTED; | ||||
break; | break; | ||||
default: | default: | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
panic("libalias:SetStateIn() unknown state"); | panic("libalias:SetStateIn() unknown state"); | ||||
#else | #else | ||||
abort(); | abort(); | ||||
#endif | #endif | ||||
} | } | ||||
lnk->data.tcp->state.in = state; | lnk->data.tcp->state.in = state; | ||||
} | } | ||||
void | void | ||||
SetStateOut(struct alias_link *lnk, int state) | SetStateOut(struct alias_link *lnk, int state) | ||||
{ | { | ||||
/* TCP output state */ | /* TCP output state */ | ||||
switch (state) { | switch (state) { | ||||
case ALIAS_TCP_STATE_DISCONNECTED: | case ALIAS_TCP_STATE_DISCONNECTED: | ||||
if (lnk->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED) | if (lnk->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED) | ||||
lnk->expire_time = TCP_EXPIRE_DEAD; | lnk->expire.timeout = TCP_EXPIRE_DEAD; | ||||
else | else | ||||
lnk->expire_time = TCP_EXPIRE_SINGLEDEAD; | lnk->expire.timeout = TCP_EXPIRE_SINGLEDEAD; | ||||
break; | break; | ||||
case ALIAS_TCP_STATE_CONNECTED: | case ALIAS_TCP_STATE_CONNECTED: | ||||
if (lnk->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED) | if (lnk->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED) | ||||
lnk->expire_time = TCP_EXPIRE_CONNECTED; | lnk->expire.timeout = TCP_EXPIRE_CONNECTED; | ||||
break; | break; | ||||
default: | default: | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
panic("libalias:SetStateOut() unknown state"); | panic("libalias:SetStateOut() unknown state"); | ||||
#else | #else | ||||
abort(); | abort(); | ||||
#endif | #endif | ||||
} | } | ||||
▲ Show 20 Lines • Show All 232 Lines • ▼ Show 20 Lines | |||||
SetExpire(struct alias_link *lnk, int expire) | SetExpire(struct alias_link *lnk, int expire) | ||||
{ | { | ||||
if (expire == 0) { | if (expire == 0) { | ||||
lnk->flags &= ~LINK_PERMANENT; | lnk->flags &= ~LINK_PERMANENT; | ||||
DeleteLink(&lnk); | DeleteLink(&lnk); | ||||
} else if (expire == -1) { | } else if (expire == -1) { | ||||
lnk->flags |= LINK_PERMANENT; | lnk->flags |= LINK_PERMANENT; | ||||
} else if (expire > 0) { | } else if (expire > 0) { | ||||
lnk->expire_time = expire; | lnk->expire.timeout = expire; | ||||
} else { | } else { | ||||
#ifdef LIBALIAS_DEBUG | #ifdef LIBALIAS_DEBUG | ||||
fprintf(stderr, "PacketAlias/SetExpire(): "); | fprintf(stderr, "PacketAlias/SetExpire(): "); | ||||
fprintf(stderr, "error in expire parameter\n"); | fprintf(stderr, "error in expire parameter\n"); | ||||
#endif | #endif | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | |||||
LibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr addr, u_short port) | LibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr addr, u_short port) | ||||
{ | { | ||||
struct server *server; | struct server *server; | ||||
int res; | int res; | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
(void)la; | (void)la; | ||||
switch (lnk->link_type) { | |||||
case LINK_PPTP: | |||||
server = NULL; | |||||
break; | |||||
default: | |||||
server = malloc(sizeof(struct server)); | server = malloc(sizeof(struct server)); | ||||
break; | |||||
} | |||||
if (server != NULL) { | if (server != NULL) { | ||||
struct server *head; | struct server *head; | ||||
server->addr = addr; | server->addr = addr; | ||||
server->port = port; | server->port = port; | ||||
head = lnk->server; | head = lnk->server; | ||||
if (head == NULL) | if (head == NULL) { | ||||
server->next = server; | server->next = server; | ||||
else { | /* not usable for outgoing connections */ | ||||
LIST_REMOVE(lnk, all.out); | |||||
} else { | |||||
struct server *s; | struct server *s; | ||||
for (s = head; s->next != head; s = s->next) | for (s = head; s->next != head; s = s->next) | ||||
; | ; | ||||
s->next = server; | s->next = server; | ||||
server->next = head; | server->next = head; | ||||
} | } | ||||
lnk->server = server; | lnk->server = server; | ||||
Show All 37 Lines | |||||
/* Static address translation */ | /* Static address translation */ | ||||
struct alias_link * | struct alias_link * | ||||
LibAliasRedirectAddr(struct libalias *la, struct in_addr src_addr, | LibAliasRedirectAddr(struct libalias *la, struct in_addr src_addr, | ||||
struct in_addr alias_addr) | struct in_addr alias_addr) | ||||
{ | { | ||||
struct alias_link *lnk; | struct alias_link *lnk; | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
lnk = AddLink(la, src_addr, NO_ADDR, alias_addr, | lnk = AddLink(la, src_addr, ANY_ADDR, alias_addr, | ||||
0, 0, 0, | 0, 0, 0, | ||||
LINK_ADDR); | LINK_ADDR); | ||||
if (lnk != NULL) { | if (lnk != NULL) { | ||||
lnk->flags |= LINK_PERMANENT; | lnk->flags |= LINK_PERMANENT; | ||||
} | } | ||||
#ifdef LIBALIAS_DEBUG | #ifdef LIBALIAS_DEBUG | ||||
else { | else { | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | #ifdef _KERNEL | ||||
LibAliasTime = time_uptime; | LibAliasTime = time_uptime; | ||||
#else | #else | ||||
LibAliasTime = time(NULL); | LibAliasTime = time(NULL); | ||||
#endif | #endif | ||||
for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) | for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) | ||||
LIST_INIT(&la->linkTableOut[i]); | LIST_INIT(&la->linkTableOut[i]); | ||||
for (i = 0; i < LINK_TABLE_IN_SIZE; i++) | for (i = 0; i < LINK_TABLE_IN_SIZE; i++) | ||||
LIST_INIT(&la->linkTableIn[i]); | LIST_INIT(&la->groupTableIn[i]); | ||||
LIST_INIT(&la->pptpList); | |||||
TAILQ_INIT(&la->checkExpire); | TAILQ_INIT(&la->checkExpire); | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
AliasSctpInit(la); | AliasSctpInit(la); | ||||
#endif | #endif | ||||
LIBALIAS_LOCK_INIT(la); | LIBALIAS_LOCK_INIT(la); | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
} else { | } else { | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
la->deleteAllLinks = 1; | la->deleteAllLinks = 1; | ||||
CleanupAliasData(la); | CleanupAliasData(la); | ||||
la->deleteAllLinks = 0; | la->deleteAllLinks = 0; | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
AliasSctpTerm(la); | AliasSctpTerm(la); | ||||
AliasSctpInit(la); | AliasSctpInit(la); | ||||
#endif | #endif | ||||
} | } | ||||
la->aliasAddress.s_addr = INADDR_ANY; | la->aliasAddress.s_addr = INADDR_ANY; | ||||
la->targetAddress.s_addr = INADDR_ANY; | la->targetAddress.s_addr = INADDR_ANY; | ||||
la->aliasPortLower = 0x8000; | |||||
la->aliasPortLength = 0x8000; | |||||
la->icmpLinkCount = 0; | la->icmpLinkCount = 0; | ||||
la->udpLinkCount = 0; | la->udpLinkCount = 0; | ||||
la->tcpLinkCount = 0; | la->tcpLinkCount = 0; | ||||
la->sctpLinkCount = 0; | la->sctpLinkCount = 0; | ||||
la->pptpLinkCount = 0; | la->pptpLinkCount = 0; | ||||
la->protoLinkCount = 0; | la->protoLinkCount = 0; | ||||
la->fragmentIdLinkCount = 0; | la->fragmentIdLinkCount = 0; | ||||
▲ Show 20 Lines • Show All 380 Lines • Show Last 20 Lines |