Lines 559-568
static struct alias_link *
Link Here
|
559 |
#define ALIAS_PORT_BASE 0x08000 |
559 |
#define ALIAS_PORT_BASE 0x08000 |
560 |
#define ALIAS_PORT_MASK 0x07fff |
560 |
#define ALIAS_PORT_MASK 0x07fff |
561 |
#define ALIAS_PORT_MASK_EVEN 0x07ffe |
561 |
#define ALIAS_PORT_MASK_EVEN 0x07ffe |
562 |
#define GET_NEW_PORT_MAX_ATTEMPTS 20 |
562 |
#define ALIAS_PORT_MAX 0x0ffff |
563 |
|
563 |
|
564 |
#define FIND_EVEN_ALIAS_BASE 1 |
564 |
#define FIND_EVEN_ALIAS_BASE 1 |
565 |
|
565 |
|
|
|
566 |
|
567 |
static int |
568 |
AllocatePortIfUnused(struct libalias *la, struct alias_link *lnk, u_short port_net) |
569 |
{ |
570 |
int go_ahead; |
571 |
struct alias_link *search_result; |
572 |
|
573 |
search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr, |
574 |
lnk->dst_port, port_net, |
575 |
lnk->link_type, 0); |
576 |
|
577 |
if (search_result == NULL) |
578 |
go_ahead = 1; |
579 |
else if (!(lnk->flags & LINK_PARTIALLY_SPECIFIED) |
580 |
&& (search_result->flags & LINK_PARTIALLY_SPECIFIED)) |
581 |
go_ahead = 1; |
582 |
else |
583 |
go_ahead = 0; |
584 |
|
585 |
if (go_ahead) { |
586 |
#ifndef NO_USE_SOCKETS |
587 |
if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS) |
588 |
&& (lnk->flags & LINK_PARTIALLY_SPECIFIED) |
589 |
&& ((lnk->link_type == LINK_TCP) || |
590 |
(lnk->link_type == LINK_UDP))) { |
591 |
if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) { |
592 |
lnk->alias_port = port_net; |
593 |
return (0); |
594 |
} |
595 |
} else { |
596 |
#endif |
597 |
lnk->alias_port = port_net; |
598 |
return (0); |
599 |
#ifndef NO_USE_SOCKETS |
600 |
} |
601 |
#endif |
602 |
} |
603 |
return (-1); |
604 |
} |
605 |
|
606 |
|
566 |
/* GetNewPort() allocates port numbers. Note that if a port number |
607 |
/* GetNewPort() allocates port numbers. Note that if a port number |
567 |
is already in use, that does not mean that it cannot be used by |
608 |
is already in use, that does not mean that it cannot be used by |
568 |
another link concurrently. This is because GetNewPort() looks for |
609 |
another link concurrently. This is because GetNewPort() looks for |
Lines 572-580
static int
Link Here
|
572 |
GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) |
613 |
GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) |
573 |
{ |
614 |
{ |
574 |
int i; |
615 |
int i; |
575 |
int max_trials; |
|
|
576 |
u_short port_sys; |
616 |
u_short port_sys; |
577 |
u_short port_net; |
|
|
578 |
|
617 |
|
579 |
LIBALIAS_LOCK_ASSERT(la); |
618 |
LIBALIAS_LOCK_ASSERT(la); |
580 |
/* |
619 |
/* |
Lines 592-598
GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
Link Here
|
592 |
* The aliasing port is automatically selected by one of |
631 |
* The aliasing port is automatically selected by one of |
593 |
* two methods below: |
632 |
* two methods below: |
594 |
*/ |
633 |
*/ |
595 |
max_trials = GET_NEW_PORT_MAX_ATTEMPTS; |
|
|
596 |
|
634 |
|
597 |
if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { |
635 |
if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { |
598 |
/* |
636 |
/* |
Lines 601-614
GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
Link Here
|
601 |
* this is already in use, the remainder of the |
639 |
* this is already in use, the remainder of the |
602 |
* trials will be random. |
640 |
* trials will be random. |
603 |
*/ |
641 |
*/ |
604 |
port_net = lnk->src_port; |
642 |
if (AllocatePortIfUnused(la, lnk, lnk->src_port) == 0) { |
605 |
port_sys = ntohs(port_net); |
643 |
return (0); |
606 |
} else { |
644 |
} |
607 |
/* First trial and all subsequent are random. */ |
|
|
608 |
port_sys = arc4random() & ALIAS_PORT_MASK; |
609 |
port_sys += ALIAS_PORT_BASE; |
610 |
port_net = htons(port_sys); |
611 |
} |
645 |
} |
|
|
646 |
/* First trial and all subsequent are random. */ |
647 |
port_sys = arc4random() & ALIAS_PORT_MASK; |
648 |
port_sys += ALIAS_PORT_BASE; |
612 |
} else if (alias_port_param >= 0 && alias_port_param < 0x10000) { |
649 |
} else if (alias_port_param >= 0 && alias_port_param < 0x10000) { |
613 |
lnk->alias_port = (u_short) alias_port_param; |
650 |
lnk->alias_port = (u_short) alias_port_param; |
614 |
return (0); |
651 |
return (0); |
Lines 622-664
GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
Link Here
|
622 |
|
659 |
|
623 |
|
660 |
|
624 |
/* Port number search */ |
661 |
/* Port number search */ |
625 |
for (i = 0; i < max_trials; i++) { |
662 |
for (i = port_sys; i <= ALIAS_PORT_MAX; i++) { |
626 |
int go_ahead; |
663 |
if (AllocatePortIfUnused(la, lnk, htons(i)) == 0) { |
627 |
struct alias_link *search_result; |
664 |
return (0); |
628 |
|
665 |
} |
629 |
search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr, |
666 |
} |
630 |
lnk->dst_port, port_net, |
667 |
for (i = port_sys - 1; i >= ALIAS_PORT_BASE; i--) { |
631 |
lnk->link_type, 0); |
668 |
if (AllocatePortIfUnused(la, lnk, htons(i)) == 0) { |
632 |
|
669 |
return (0); |
633 |
if (search_result == NULL) |
|
|
634 |
go_ahead = 1; |
635 |
else if (!(lnk->flags & LINK_PARTIALLY_SPECIFIED) |
636 |
&& (search_result->flags & LINK_PARTIALLY_SPECIFIED)) |
637 |
go_ahead = 1; |
638 |
else |
639 |
go_ahead = 0; |
640 |
|
641 |
if (go_ahead) { |
642 |
#ifndef NO_USE_SOCKETS |
643 |
if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS) |
644 |
&& (lnk->flags & LINK_PARTIALLY_SPECIFIED) |
645 |
&& ((lnk->link_type == LINK_TCP) || |
646 |
(lnk->link_type == LINK_UDP))) { |
647 |
if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) { |
648 |
lnk->alias_port = port_net; |
649 |
return (0); |
650 |
} |
651 |
} else { |
652 |
#endif |
653 |
lnk->alias_port = port_net; |
654 |
return (0); |
655 |
#ifndef NO_USE_SOCKETS |
656 |
} |
657 |
#endif |
658 |
} |
670 |
} |
659 |
port_sys = arc4random() & ALIAS_PORT_MASK; |
|
|
660 |
port_sys += ALIAS_PORT_BASE; |
661 |
port_net = htons(port_sys); |
662 |
} |
671 |
} |
663 |
|
672 |
|
664 |
#ifdef LIBALIAS_DEBUG |
673 |
#ifdef LIBALIAS_DEBUG |
Lines 731-740
FindNewPortGroup(struct libalias *la,
Link Here
|
731 |
u_char proto, |
740 |
u_char proto, |
732 |
u_char align) |
741 |
u_char align) |
733 |
{ |
742 |
{ |
734 |
int i, j; |
743 |
struct alias_link *search_result; |
735 |
int max_trials; |
744 |
int i; |
736 |
u_short port_sys; |
745 |
u_short port_sys; |
737 |
int link_type; |
746 |
int link_type; |
|
|
747 |
int consecutive_matches; |
738 |
|
748 |
|
739 |
LIBALIAS_LOCK_ASSERT(la); |
749 |
LIBALIAS_LOCK_ASSERT(la); |
740 |
/* |
750 |
/* |
Lines 757-764
FindNewPortGroup(struct libalias *la,
Link Here
|
757 |
* The aliasing port is automatically selected by one of two |
767 |
* The aliasing port is automatically selected by one of two |
758 |
* methods below: |
768 |
* methods below: |
759 |
*/ |
769 |
*/ |
760 |
max_trials = GET_NEW_PORT_MAX_ATTEMPTS; |
|
|
761 |
|
762 |
if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { |
770 |
if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { |
763 |
/* |
771 |
/* |
764 |
* When the ALIAS_SAME_PORTS option is chosen, the first |
772 |
* When the ALIAS_SAME_PORTS option is chosen, the first |
Lines 779-805
FindNewPortGroup(struct libalias *la,
Link Here
|
779 |
} |
787 |
} |
780 |
|
788 |
|
781 |
/* Port number search */ |
789 |
/* Port number search */ |
782 |
for (i = 0; i < max_trials; i++) { |
790 |
consecutive_matches = 0; |
783 |
|
791 |
for (i = port_sys; i <= ALIAS_PORT_MAX; i++) { |
784 |
struct alias_link *search_result; |
792 |
if ((search_result = FindLinkIn(la, dst_addr, |
785 |
|
793 |
alias_addr, dst_port, htons(i), |
786 |
for (j = 0; j < port_count; j++) |
794 |
link_type, 0)) != NULL) { |
787 |
if ((search_result = FindLinkIn(la, dst_addr, |
795 |
consecutive_matches++; |
788 |
alias_addr, dst_port, htons(port_sys + j), |
796 |
if (consecutive_matches == port_count) |
789 |
link_type, 0)) != NULL) |
797 |
return (htons(i - port_count + 1)); |
790 |
break; |
798 |
} else { |
791 |
|
799 |
consecutive_matches = 0; |
792 |
/* Found a good range, return base */ |
800 |
if (align == FIND_EVEN_ALIAS_BASE && (i % 2) == 0) |
793 |
if (j == port_count) |
801 |
i++; |
794 |
return (htons(port_sys)); |
802 |
} |
795 |
|
803 |
} |
796 |
/* Find a new base to try */ |
804 |
consecutive_matches = 0; |
797 |
if (align == FIND_EVEN_ALIAS_BASE) |
805 |
if (align == FIND_EVEN_ALIAS_BASE && (port_count % 2) != 0) |
798 |
port_sys = arc4random() & ALIAS_PORT_MASK_EVEN; |
806 |
port_sys--; |
799 |
else |
807 |
for (i = port_sys - 1; i >= ALIAS_PORT_BASE; i--) { |
800 |
port_sys = arc4random() & ALIAS_PORT_MASK; |
808 |
if ((search_result = FindLinkIn(la, dst_addr, |
801 |
|
809 |
alias_addr, dst_port, htons(i), |
802 |
port_sys += ALIAS_PORT_BASE; |
810 |
link_type, 0)) != NULL) { |
|
|
811 |
consecutive_matches++; |
812 |
if (consecutive_matches == port_count) |
813 |
return (htons(i)); |
814 |
} else { |
815 |
consecutive_matches = 0; |
816 |
if (align == FIND_EVEN_ALIAS_BASE && (i % 2) == 0) |
817 |
i--; |
818 |
} |
803 |
} |
819 |
} |
804 |
|
820 |
|
805 |
#ifdef LIBALIAS_DEBUG |
821 |
#ifdef LIBALIAS_DEBUG |
806 |
- |
|
|