Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/libalias/alias_db.c
| Show First 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | |||||
| #include <net/if.h> | #include <net/if.h> | ||||
| #else | #else | ||||
| #include "alias.h" | #include "alias.h" | ||||
| #include "alias_local.h" | #include "alias_local.h" | ||||
| #include "alias_mod.h" | #include "alias_mod.h" | ||||
| #endif | #endif | ||||
| static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead); | static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead); | ||||
| int LibAliasTime; | |||||
| /* | /* | ||||
| Constants (note: constants are also defined | Constants (note: constants are also defined | ||||
| near relevant functions or structs) | near relevant functions or structs) | ||||
| */ | */ | ||||
| /* Parameters used for cleanup of expired links */ | |||||
| /* NOTE: ALIAS_CLEANUP_INTERVAL_SECS must be less then LINK_TABLE_OUT_SIZE */ | |||||
| #define ALIAS_CLEANUP_INTERVAL_SECS 64 | |||||
| #define ALIAS_CLEANUP_MAX_SPOKES (LINK_TABLE_OUT_SIZE/5) | |||||
| /* Timeouts (in seconds) for different link types */ | /* Timeouts (in seconds) for different link types */ | ||||
| #define ICMP_EXPIRE_TIME 60 | #define ICMP_EXPIRE_TIME 60 | ||||
| #define UDP_EXPIRE_TIME 60 | #define UDP_EXPIRE_TIME 60 | ||||
| #define PROTO_EXPIRE_TIME 60 | #define PROTO_EXPIRE_TIME 60 | ||||
| #define FRAGMENT_ID_EXPIRE_TIME 10 | #define FRAGMENT_ID_EXPIRE_TIME 10 | ||||
| #define FRAGMENT_PTR_EXPIRE_TIME 30 | #define FRAGMENT_PTR_EXPIRE_TIME 30 | ||||
| /* TCP link expire time for different cases */ | /* TCP link expire time for different cases */ | ||||
| ▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | #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 */ | 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; | LIST_ENTRY (alias_link) list_out; | ||||
| LIST_ENTRY (alias_link) list_in; | LIST_ENTRY (alias_link) list_in; | ||||
| TAILQ_ENTRY (alias_link) list_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 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | |||||
| /* Internal routines for finding, deleting and adding links | /* Internal routines for finding, deleting and adding links | ||||
| Port Allocation: | Port Allocation: | ||||
| GetNewPort() -- find and reserve new alias port number | GetNewPort() -- find and reserve new alias port number | ||||
| GetSocket() -- try to allocate a socket for a given port | GetSocket() -- try to allocate a socket for a given port | ||||
| Link creation and deletion: | Link creation and deletion: | ||||
| CleanupAliasData() - remove all link chains from lookup table | CleanupAliasData() - remove all link chains from lookup table | ||||
| IncrementalCleanup() - look for stale links in a single chain | CleanupLink() - look for a stale link | ||||
| DeleteLink() - remove link | DeleteLink() - remove link | ||||
| AddLink() - add link | AddLink() - add link | ||||
| ReLink() - change link | ReLink() - change link | ||||
| Link search: | Link search: | ||||
| FindLinkOut() - find link for outgoing packets | FindLinkOut() - find link for outgoing packets | ||||
| FindLinkIn() - find link for incoming packets | FindLinkIn() - find link for incoming packets | ||||
| Port search: | 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 *); | ||||
| static void IncrementalCleanup(struct libalias *); | static void CleanupLink(struct libalias *, struct alias_link **); | ||||
| static void DeleteLink(struct alias_link *); | static void DeleteLink(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); | ||||
| ▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| static void | static void | ||||
| CleanupAliasData(struct libalias *la) | CleanupAliasData(struct libalias *la) | ||||
| { | { | ||||
| struct alias_link *lnk; | struct alias_link *lnk, *lnk_tmp; | ||||
| int i; | |||||
| LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
| for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) { | |||||
| lnk = LIST_FIRST(&la->linkTableOut[i]); | |||||
| while (lnk != NULL) { | |||||
| struct alias_link *link_next = LIST_NEXT(lnk, list_out); | |||||
| DeleteLink(lnk); | |||||
| lnk = link_next; | |||||
| } | |||||
| } | |||||
| la->cleanupIndex = 0; | /* permanent entries may stay */ | ||||
| TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, list_expire, lnk_tmp) | |||||
| DeleteLink(&lnk); | |||||
| } | } | ||||
| static void | static void | ||||
| IncrementalCleanup(struct libalias *la) | CleanupLink(struct libalias *la, struct alias_link **lnk) | ||||
| { | { | ||||
| struct alias_link *lnk, *lnk_tmp; | |||||
| LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
| LIST_FOREACH_SAFE(lnk, &la->linkTableOut[la->cleanupIndex++], | |||||
| list_out, lnk_tmp) { | if (lnk == NULL || *lnk == NULL) | ||||
| if (la->timeStamp - lnk->timestamp > lnk->expire_time) | return; | ||||
| if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire_time) { | |||||
| DeleteLink(lnk); | DeleteLink(lnk); | ||||
| if ((*lnk) == NULL) | |||||
| return; | |||||
| } | } | ||||
| if (la->cleanupIndex == LINK_TABLE_OUT_SIZE) | /* move to end, swap may fail on a single entry list */ | ||||
| la->cleanupIndex = 0; | TAILQ_REMOVE(&la->checkExpire, (*lnk), list_expire); | ||||
| TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), list_expire); | |||||
| } | } | ||||
| static void | static void | ||||
| DeleteLink(struct alias_link *lnk) | DeleteLink(struct alias_link **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 | ||||
| Show All 11 Lines | do { | ||||
| free(curr); | free(curr); | ||||
| } while ((curr = next) != head); | } while ((curr = next) != head); | ||||
| } | } | ||||
| /* Adjust output table pointers */ | /* Adjust output table pointers */ | ||||
| LIST_REMOVE(lnk, list_out); | LIST_REMOVE(lnk, list_out); | ||||
| /* Adjust input table pointers */ | /* Adjust input table pointers */ | ||||
| LIST_REMOVE(lnk, list_in); | LIST_REMOVE(lnk, list_in); | ||||
| /* remove from housekeeping */ | |||||
| TAILQ_REMOVE(&la->checkExpire, lnk, list_expire); | |||||
| #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 | ||||
| /* Link-type dependent cleanup */ | /* Link-type dependent cleanup */ | ||||
| Show All 23 Lines | case LINK_ADDR: | ||||
| break; | break; | ||||
| default: | default: | ||||
| la->protoLinkCount--; | la->protoLinkCount--; | ||||
| break; | break; | ||||
| } | } | ||||
| /* Free memory */ | /* Free memory */ | ||||
| free(lnk); | free(lnk); | ||||
| *plnk = NULL; | |||||
| /* Write statistics, if logging enabled */ | /* Write statistics, if logging enabled */ | ||||
| if (la->packetAliasMode & PKT_ALIAS_LOG) { | if (la->packetAliasMode & PKT_ALIAS_LOG) { | ||||
| ShowAliasStats(la); | ShowAliasStats(la); | ||||
| } | } | ||||
| } | } | ||||
| struct alias_link * | struct alias_link * | ||||
| Show All 18 Lines | if (lnk != NULL) { | ||||
| 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 = la->timeStamp; | 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_time = ICMP_EXPIRE_TIME; | ||||
| break; | break; | ||||
| case LINK_UDP: | case LINK_UDP: | ||||
| lnk->expire_time = UDP_EXPIRE_TIME; | lnk->expire_time = UDP_EXPIRE_TIME; | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | #endif | ||||
| /* 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, list_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); | start_point = StartPointIn(alias_addr, lnk->alias_port, link_type); | ||||
| LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in); | LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in); | ||||
| /* Include the element into the housekeeping list */ | |||||
| TAILQ_INSERT_TAIL(&la->checkExpire, lnk, list_expire); | |||||
| } else { | } else { | ||||
| #ifdef LIBALIAS_DEBUG | #ifdef LIBALIAS_DEBUG | ||||
| fprintf(stderr, "PacketAlias/AddLink(): "); | fprintf(stderr, "PacketAlias/AddLink(): "); | ||||
| fprintf(stderr, "malloc() call failed.\n"); | fprintf(stderr, "malloc() call failed.\n"); | ||||
| #endif | #endif | ||||
| } | } | ||||
| if (la->packetAliasMode & PKT_ALIAS_LOG) { | if (la->packetAliasMode & PKT_ALIAS_LOG) { | ||||
| ShowAliasStats(la); | ShowAliasStats(la); | ||||
| Show All 24 Lines | new_lnk = AddLink(la, src_addr, dst_addr, alias_addr, | ||||
| 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); | ||||
| return (new_lnk); | return (new_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, | ||||
| int link_type, | int link_type, | ||||
| int replace_partial_links) | int replace_partial_links) | ||||
| { | { | ||||
| u_int i; | 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); | i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type); | ||||
| LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) { | LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) { | ||||
| if (lnk->dst_addr.s_addr == dst_addr.s_addr && | if (lnk->dst_addr.s_addr == dst_addr.s_addr && | ||||
| lnk->src_addr.s_addr == src_addr.s_addr && | lnk->src_addr.s_addr == src_addr.s_addr && | ||||
| lnk->src_port == src_port && | lnk->src_port == src_port && | ||||
| lnk->dst_port == dst_port && | lnk->dst_port == dst_port && | ||||
| lnk->link_type == link_type && | lnk->link_type == link_type && | ||||
| lnk->server == NULL) { | lnk->server == NULL) | ||||
| lnk->timestamp = la->timeStamp; | |||||
| break; | 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 (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 = _FindLinkOut(la, src_addr, dst_addr, src_port, 0, | ||||
| link_type, 0); | link_type, 0); | ||||
| if (lnk == NULL) | if (lnk == NULL) | ||||
| lnk = _FindLinkOut(la, src_addr, NO_ADDR, src_port, | lnk = _FindLinkOut(la, src_addr, NO_ADDR, src_port, | ||||
| dst_port, link_type, 0); | dst_port, link_type, 0); | ||||
| ▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | if (!(flags & LINK_PARTIALLY_SPECIFIED)) { | ||||
| && lnk->link_type == link_type | && lnk->link_type == link_type | ||||
| && lnk->dst_addr.s_addr == dst_addr.s_addr) { | && lnk->dst_addr.s_addr == dst_addr.s_addr) { | ||||
| if (lnk_unknown_dst_port == NULL) | if (lnk_unknown_dst_port == NULL) | ||||
| lnk_unknown_dst_port = lnk; | lnk_unknown_dst_port = lnk; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| CleanupLink(la, &lnk_fully_specified); | |||||
| if (lnk_fully_specified != NULL) { | if (lnk_fully_specified != NULL) { | ||||
| lnk_fully_specified->timestamp = la->timeStamp; | lnk_fully_specified->timestamp = LibAliasTime; | ||||
| lnk = lnk_fully_specified; | lnk = lnk_fully_specified; | ||||
| } else if (lnk_unknown_dst_port != NULL) | } else if (lnk_unknown_dst_port != NULL) | ||||
| lnk = lnk_unknown_dst_port; | lnk = lnk_unknown_dst_port; | ||||
| else if (lnk_unknown_dst_addr != NULL) | else if (lnk_unknown_dst_addr != NULL) | ||||
| lnk = lnk_unknown_dst_addr; | lnk = lnk_unknown_dst_addr; | ||||
| else if (lnk_unknown_all != NULL) | else if (lnk_unknown_all != NULL) | ||||
| lnk = lnk_unknown_all; | lnk = lnk_unknown_all; | ||||
| else | else | ||||
| ▲ Show 20 Lines • Show All 319 Lines • ▼ Show 20 Lines | FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr, | ||||
| i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); | i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); | ||||
| LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) | LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) | ||||
| if (lnk->link_type == LINK_PPTP && | if (lnk->link_type == LINK_PPTP && | ||||
| 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 && | ||||
| lnk->src_port == src_call_id) | lnk->src_port == src_call_id) | ||||
| break; | break; | ||||
| CleanupLink(la, &lnk); | |||||
| return (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; | 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); | i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); | ||||
| LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) | LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) | ||||
| if (lnk->link_type == LINK_PPTP && | if (lnk->link_type == LINK_PPTP && | ||||
| 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 && | ||||
| lnk->dst_port == dst_call_id) | lnk->dst_port == dst_call_id) | ||||
| break; | break; | ||||
| CleanupLink(la, &lnk); | |||||
| return (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; | 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); | i = StartPointIn(alias_addr, 0, LINK_PPTP); | ||||
| LIST_FOREACH(lnk, &la->linkTableIn[i], list_in) | LIST_FOREACH(lnk, &la->linkTableIn[i], list_in) | ||||
| if (lnk->link_type == LINK_PPTP && | if (lnk->link_type == LINK_PPTP && | ||||
| 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) | lnk->dst_port == dst_call_id) | ||||
| break; | break; | ||||
| CleanupLink(la, &lnk); | |||||
| return (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) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 411 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); | ||||
| } 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 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | /* | ||||
| every 60 seconds. | every 60 seconds. | ||||
| (prototype in alias_local.h) | (prototype in alias_local.h) | ||||
| */ | */ | ||||
| void | void | ||||
| HouseKeeping(struct libalias *la) | HouseKeeping(struct libalias *la) | ||||
| { | { | ||||
| int i, n; | struct alias_link * lnk = TAILQ_FIRST(&la->checkExpire); | ||||
| #ifndef _KERNEL | static int packets = 0; | ||||
| struct timeval tv; | |||||
| #endif | |||||
| /* | |||||
| * User space time/gettimeofday/... is very expensive. | |||||
| * Kernel space cache trashing is unnecessary. | |||||
| * | |||||
| * Reduce the amount of house keeping work substantially by | |||||
| * sampling over the packets. | |||||
| * | |||||
| * TODO: choose a dynamic sampling interval. | |||||
| */ | |||||
| if (packets++ < 1000) | |||||
| return; | |||||
| packets = 0; | |||||
| LIBALIAS_LOCK_ASSERT(la); | LIBALIAS_LOCK_ASSERT(la); | ||||
| /* | /* | ||||
| * Save system time (seconds) in global variable timeStamp for use | * Save system time (seconds) in global variable LibAliasTime | ||||
| * by other functions. This is done so as not to unnecessarily | * for use by other functions. This is done so as not to | ||||
| * waste timeline by making system calls. | * unnecessarily waste timeline by making system calls. | ||||
| */ | */ | ||||
| #ifdef _KERNEL | #ifdef _KERNEL | ||||
| la->timeStamp = time_uptime; | LibAliasTime = time_uptime; | ||||
| #else | #else | ||||
| gettimeofday(&tv, NULL); | LibAliasTime = time(NULL); | ||||
| la->timeStamp = tv.tv_sec; | |||||
| #endif | #endif | ||||
| CleanupLink(la, &lnk); | |||||
| /* Compute number of spokes (output table link chains) to cover */ | |||||
| n = LINK_TABLE_OUT_SIZE * (la->timeStamp - la->lastCleanupTime); | |||||
| n /= ALIAS_CLEANUP_INTERVAL_SECS; | |||||
| /* Handle different cases */ | |||||
| if (n > 0) { | |||||
| if (n > ALIAS_CLEANUP_MAX_SPOKES) | |||||
| n = ALIAS_CLEANUP_MAX_SPOKES; | |||||
| la->lastCleanupTime = la->timeStamp; | |||||
| for (i = 0; i < n; i++) | |||||
| IncrementalCleanup(la); | |||||
| } else if (n < 0) { | |||||
| #ifdef LIBALIAS_DEBUG | |||||
| fprintf(stderr, "PacketAlias/HouseKeeping(): "); | |||||
| fprintf(stderr, "something unexpected in time values\n"); | |||||
| #endif | |||||
| la->lastCleanupTime = la->timeStamp; | |||||
| } | } | ||||
| } | |||||
| /* 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); | ||||
| if (~la->packetAliasMode & PKT_ALIAS_LOG) { | if (~la->packetAliasMode & PKT_ALIAS_LOG) { | ||||
| #ifdef _KERNEL | #ifdef _KERNEL | ||||
| ▲ Show 20 Lines • Show All 209 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; | la->deleteAllLinks = 1; | ||||
| DeleteLink(lnk); | DeleteLink(&lnk); | ||||
| la->deleteAllLinks = 0; | 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); | ||||
| Show All 30 Lines | finishoff(void) | ||||
| while (!LIST_EMPTY(&instancehead)) | while (!LIST_EMPTY(&instancehead)) | ||||
| LibAliasUninit(LIST_FIRST(&instancehead)); | LibAliasUninit(LIST_FIRST(&instancehead)); | ||||
| } | } | ||||
| struct libalias * | struct libalias * | ||||
| LibAliasInit(struct libalias *la) | LibAliasInit(struct libalias *la) | ||||
| { | { | ||||
| int i; | int i; | ||||
| #ifndef _KERNEL | |||||
| struct timeval tv; | |||||
| #endif | |||||
| if (la == NULL) { | if (la == NULL) { | ||||
| #ifdef _KERNEL | #ifdef _KERNEL | ||||
| #undef malloc /* XXX: ugly */ | #undef malloc /* XXX: ugly */ | ||||
| la = malloc(sizeof *la, M_ALIAS, M_WAITOK | M_ZERO); | la = malloc(sizeof *la, M_ALIAS, M_WAITOK | M_ZERO); | ||||
| #else | #else | ||||
| la = calloc(sizeof *la, 1); | la = calloc(sizeof *la, 1); | ||||
| if (la == NULL) | if (la == NULL) | ||||
| return (la); | return (la); | ||||
| #endif | #endif | ||||
| #ifndef _KERNEL | #ifndef _KERNEL | ||||
| /* kernel cleans up on module unload */ | /* kernel cleans up on module unload */ | ||||
| if (LIST_EMPTY(&instancehead)) | if (LIST_EMPTY(&instancehead)) | ||||
| atexit(finishoff); | atexit(finishoff); | ||||
| #endif | #endif | ||||
| LIST_INSERT_HEAD(&instancehead, la, instancelist); | LIST_INSERT_HEAD(&instancehead, la, instancelist); | ||||
| #ifdef _KERNEL | #ifdef _KERNEL | ||||
| la->timeStamp = time_uptime; | LibAliasTime = time_uptime; | ||||
| la->lastCleanupTime = time_uptime; | |||||
| #else | #else | ||||
| gettimeofday(&tv, NULL); | LibAliasTime = time(NULL); | ||||
| la->timeStamp = tv.tv_sec; | |||||
| la->lastCleanupTime = tv.tv_sec; | |||||
| #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->linkTableIn[i]); | ||||
| 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; | ||||
| ▲ Show 20 Lines • Show All 398 Lines • Show Last 20 Lines | |||||