Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/libalias/alias_db.c
Show First 20 Lines • Show All 551 Lines • ▼ Show 20 Lines | Port search: | ||||
FindNewPortGroup() - find an available group of ports | FindNewPortGroup() - find an available group of ports | ||||
*/ | */ | ||||
/* 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 *, int); | ||||
static void CleanupLink(struct libalias *, struct alias_link **); | static void CleanupLink(struct libalias *, struct alias_link **, int); | ||||
static void DeleteLink(struct alias_link **); | static void DeleteLink(struct alias_link **, int); | ||||
static struct alias_link * | static struct alias_link * | ||||
UseLink(struct libalias *, 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, 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); | ||||
static u_short _RandomPort(struct libalias *la); | static u_short _RandomPort(struct libalias *la); | ||||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | #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, int deletePermanent) | ||||
{ | { | ||||
struct alias_link *lnk, *lnk_tmp; | struct alias_link *lnk, *lnk_tmp; | ||||
u_int i; | 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, expire.list, lnk_tmp) | TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, expire.list, lnk_tmp) | ||||
DeleteLink(&lnk); | DeleteLink(&lnk, deletePermanent); | ||||
for (i = 0; i < LINK_TABLE_IN_SIZE; i++) { | for (i = 0; i < LINK_TABLE_IN_SIZE; i++) { | ||||
struct group_in *grp, *grp_tmp; | struct group_in *grp, *grp_tmp; | ||||
LIST_FOREACH_SAFE(grp, &la->groupTableIn[i], group_in, grp_tmp) | LIST_FOREACH_SAFE(grp, &la->groupTableIn[i], group_in, grp_tmp) | ||||
if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) { | if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) { | ||||
LIST_REMOVE(grp, group_in); | LIST_REMOVE(grp, group_in); | ||||
free(grp); | free(grp); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
CleanupLink(struct libalias *la, struct alias_link **lnk) | CleanupLink(struct libalias *la, struct alias_link **lnk, int deletePermanent) | ||||
{ | { | ||||
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.time) { | ||||
DeleteLink(lnk); | DeleteLink(lnk, deletePermanent); | ||||
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), expire.list); | TAILQ_REMOVE(&la->checkExpire, (*lnk), expire.list); | ||||
TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), expire.list); | TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), expire.list); | ||||
} | } | ||||
static struct alias_link * | static struct alias_link * | ||||
UseLink(struct libalias *la, struct alias_link *lnk) | UseLink(struct libalias *la, struct alias_link *lnk) | ||||
{ | { | ||||
CleanupLink(la, &lnk); | CleanupLink(la, &lnk, 0); | ||||
if (lnk != NULL) | if (lnk != NULL) | ||||
lnk->timestamp = LibAliasTime; | lnk->timestamp = LibAliasTime; | ||||
return (lnk); | return (lnk); | ||||
} | } | ||||
static void | static void | ||||
DeleteLink(struct alias_link **plnk) | DeleteLink(struct alias_link **plnk, int deletePermanent) | ||||
{ | { | ||||
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 (!deletePermanent && (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) { | switch (lnk->link_type) { | ||||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | |||||
static struct alias_link * | static struct alias_link * | ||||
ReLink(struct alias_link *old_lnk, | ReLink(struct alias_link *old_lnk, | ||||
struct in_addr src_addr, | struct in_addr src_addr, | ||||
struct in_addr dst_addr, | struct in_addr dst_addr, | ||||
struct in_addr alias_addr, | struct in_addr alias_addr, | ||||
u_short src_port, | u_short src_port, | ||||
u_short dst_port, | u_short dst_port, | ||||
int alias_port_param, | int alias_port_param, | ||||
int link_type) | int link_type, | ||||
int deletePermanent) | |||||
{ | { | ||||
struct alias_link *new_lnk; | struct alias_link *new_lnk; | ||||
struct libalias *la = old_lnk->la; | struct libalias *la = old_lnk->la; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
new_lnk = AddLink(la, src_addr, dst_addr, alias_addr, | new_lnk = AddLink(la, src_addr, dst_addr, alias_addr, | ||||
src_port, dst_port, alias_port_param, | src_port, dst_port, alias_port_param, | ||||
link_type); | link_type); | ||||
#ifndef NO_FW_PUNCH | #ifndef NO_FW_PUNCH | ||||
if (new_lnk != NULL && | if (new_lnk != NULL && | ||||
old_lnk->link_type == LINK_TCP && | old_lnk->link_type == LINK_TCP && | ||||
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, deletePermanent); | ||||
return (new_lnk); | return (new_lnk); | ||||
} | } | ||||
#define OUTGUARD \ | #define OUTGUARD \ | ||||
if (lnk->src_port != src_port || \ | if (lnk->src_port != src_port || \ | ||||
lnk->src_addr.s_addr != src_addr.s_addr || \ | 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 || \ | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | if (lnk == NULL && | ||||
(dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) { | (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) { | ||||
lnk = _SearchLinkOut(la, src_addr, ANY_ADDR, src_port, 0, | lnk = _SearchLinkOut(la, src_addr, ANY_ADDR, src_port, 0, | ||||
link_type); | 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, 0); | ||||
} | } | ||||
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, | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | _FindLinkIn(struct libalias *la, struct in_addr dst_addr, | ||||
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; | ||||
} else { | } 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, 0); | ||||
} | } | ||||
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, | ||||
▲ Show 20 Lines • Show All 746 Lines • ▼ Show 20 Lines | else | ||||
lnk->data.tcp->state.index = i; | lnk->data.tcp->state.index = i; | ||||
} | } | ||||
void | void | ||||
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, 0); | ||||
} 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.time = 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"); | ||||
Show All 14 Lines | |||||
} | } | ||||
void | void | ||||
SetDestCallId(struct alias_link *lnk, u_int16_t cid) | SetDestCallId(struct alias_link *lnk, u_int16_t cid) | ||||
{ | { | ||||
struct libalias *la = lnk->la; | struct libalias *la = lnk->la; | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
la->deleteAllLinks = 1; | (void)la; | ||||
ReLink(lnk, lnk->src_addr, lnk->dst_addr, lnk->alias_addr, | ReLink(lnk, lnk->src_addr, lnk->dst_addr, lnk->alias_addr, | ||||
lnk->src_port, cid, lnk->alias_port, lnk->link_type); | lnk->src_port, cid, lnk->alias_port, lnk->link_type, 1); | ||||
la->deleteAllLinks = 0; | |||||
} | } | ||||
/* Miscellaneous Functions | /* Miscellaneous Functions | ||||
HouseKeeping() | HouseKeeping() | ||||
InitPacketAliasLog() | InitPacketAliasLog() | ||||
UninitPacketAliasLog() | UninitPacketAliasLog() | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (now != LibAliasTime) { | ||||
LibAliasTime = now; | LibAliasTime = now; | ||||
} | } | ||||
} | } | ||||
/* Do a cleanup for the first packets of the new second only */ | /* Do a cleanup for the first packets of the new second only */ | ||||
if (packets < (la->udpLinkCount + la->tcpLinkCount)) { | if (packets < (la->udpLinkCount + la->tcpLinkCount)) { | ||||
struct alias_link * lnk = TAILQ_FIRST(&la->checkExpire); | struct alias_link * lnk = TAILQ_FIRST(&la->checkExpire); | ||||
CleanupLink(la, &lnk); | CleanupLink(la, &lnk, 0); | ||||
} | } | ||||
} | } | ||||
/* Init the log file and enable logging */ | /* Init the log file and enable logging */ | ||||
static int | static int | ||||
InitPacketAliasLog(struct libalias *la) | InitPacketAliasLog(struct libalias *la) | ||||
{ | { | ||||
LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* This is a dangerous function to put in the API, | /* This is a dangerous function to put in the API, | ||||
because an invalid pointer can crash the program. */ | because an invalid pointer can crash the program. */ | ||||
void | void | ||||
LibAliasRedirectDelete(struct libalias *la, struct alias_link *lnk) | LibAliasRedirectDelete(struct libalias *la, struct alias_link *lnk) | ||||
{ | { | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
la->deleteAllLinks = 1; | (void)la; | ||||
DeleteLink(&lnk); | DeleteLink(&lnk, 1); | ||||
la->deleteAllLinks = 0; | |||||
LIBALIAS_UNLOCK(la); | LIBALIAS_UNLOCK(la); | ||||
} | } | ||||
void | void | ||||
LibAliasSetAddress(struct libalias *la, struct in_addr addr) | LibAliasSetAddress(struct libalias *la, struct in_addr addr) | ||||
{ | { | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE | if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE | ||||
&& la->aliasAddress.s_addr != addr.s_addr) | && la->aliasAddress.s_addr != addr.s_addr) | ||||
CleanupAliasData(la); | CleanupAliasData(la, 0); | ||||
la->aliasAddress = addr; | la->aliasAddress = addr; | ||||
LIBALIAS_UNLOCK(la); | LIBALIAS_UNLOCK(la); | ||||
} | } | ||||
void | void | ||||
LibAliasSetAliasPortRange(struct libalias *la, u_short port_low, | LibAliasSetAliasPortRange(struct libalias *la, u_short port_low, | ||||
u_short port_high) | u_short port_high) | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | #endif | ||||
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; | CleanupAliasData(la, 1); | ||||
CleanupAliasData(la); | |||||
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; | ||||
Show All 27 Lines | |||||
void | void | ||||
LibAliasUninit(struct libalias *la) | LibAliasUninit(struct libalias *la) | ||||
{ | { | ||||
LIBALIAS_LOCK(la); | LIBALIAS_LOCK(la); | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
AliasSctpTerm(la); | AliasSctpTerm(la); | ||||
#endif | #endif | ||||
la->deleteAllLinks = 1; | CleanupAliasData(la, 1); | ||||
CleanupAliasData(la); | |||||
la->deleteAllLinks = 0; | |||||
UninitPacketAliasLog(la); | UninitPacketAliasLog(la); | ||||
#ifndef NO_FW_PUNCH | #ifndef NO_FW_PUNCH | ||||
UninitPunchFW(la); | UninitPunchFW(la); | ||||
#endif | #endif | ||||
LIST_REMOVE(la, instancelist); | LIST_REMOVE(la, instancelist); | ||||
LIBALIAS_UNLOCK(la); | LIBALIAS_UNLOCK(la); | ||||
LIBALIAS_LOCK_DESTROY(la); | LIBALIAS_LOCK_DESTROY(la); | ||||
free(la); | free(la); | ||||
▲ Show 20 Lines • Show All 331 Lines • Show Last 20 Lines |