View | Details | Raw Unified | Return to bug 220101
Collapse All | Expand All

(-)b/sys/netinet/libalias/alias_db.c (-73 / +88 lines)
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
- 

Return to bug 220101