@@ -3,17 +3,36 @@ package portallocator
33import (
44 "errors"
55 "fmt"
6+ "github.com/sirupsen/logrus"
67 "net"
78 "sync"
89)
910
10- const (
11- // DefaultPortRangeStart indicates the first port in port range
12- DefaultPortRangeStart = 49153
13- // DefaultPortRangeEnd indicates the last port in port range
14- DefaultPortRangeEnd = 65535
11+ var (
12+ // defaultPortRangeStart indicates the first port in port range
13+ defaultPortRangeStart = 49153
14+ // defaultPortRangeEnd indicates the last port in port range
15+ // consistent with default /proc/sys/net/ipv4/ip_local_port_range
16+ // upper bound on linux
17+ defaultPortRangeEnd = 60999
1518)
1619
20+ func sanitizePortRange (start int , end int ) (newStart , newEnd int , err error ) {
21+ if start > defaultPortRangeEnd || end < defaultPortRangeStart || start > end {
22+ return 0 , 0 , fmt .Errorf ("Request out allowed range [%v, %v]" ,
23+ defaultPortRangeStart , defaultPortRangeEnd )
24+ }
25+ err = nil
26+ newStart , newEnd = start , end
27+ if start < defaultPortRangeStart {
28+ newStart = defaultPortRangeStart
29+ }
30+ if end > defaultPortRangeEnd {
31+ newEnd = defaultPortRangeEnd
32+ }
33+ return
34+ }
35+
1736type ipMapping map [string ]protoMap
1837
1938var (
@@ -92,11 +111,19 @@ func Get() *PortAllocator {
92111 return instance
93112}
94113
95- func newInstance () * PortAllocator {
114+ func getDefaultPortRange () ( int , int ) {
96115 start , end , err := getDynamicPortRange ()
116+ if err == nil {
117+ start , end , err = sanitizePortRange (start , end )
118+ }
97119 if err != nil {
98- start , end = DefaultPortRangeStart , DefaultPortRangeEnd
120+ start , end = defaultPortRangeStart , defaultPortRangeEnd
99121 }
122+ return start , end
123+ }
124+
125+ func newInstance () * PortAllocator {
126+ start , end := getDefaultPortRange ()
100127 return & PortAllocator {
101128 ipMap : ipMapping {},
102129 Begin : start ,
@@ -170,6 +197,35 @@ func (p *PortAllocator) ReleasePort(ip net.IP, proto string, port int) error {
170197 return nil
171198}
172199
200+ // SetPortRange sets dynamic port allocation range.
201+ // if both portBegin and portEnd are 0, the port range reverts to default
202+ // value. Otherwise they are sanitized against the default values to
203+ // ensure their validity.
204+ func (p * PortAllocator ) SetPortRange (portBegin , portEnd int ) error {
205+ // if begin and end is zero, revert to default values
206+ var begin , end int
207+ var err error
208+ if portBegin == 0 && portEnd == 0 {
209+ begin , end = getDefaultPortRange ()
210+
211+ } else {
212+ begin , end , err = sanitizePortRange (portBegin , portEnd )
213+ if err != nil {
214+ return err
215+ }
216+ }
217+ logrus .Debugf ("Setting up port allocator to range %v-%v, current %v-%v" ,
218+ begin , end , p .Begin , p .End )
219+ p .mutex .Lock ()
220+ defer p .mutex .Unlock ()
221+ if p .Begin == begin && p .End == end {
222+ return nil
223+ }
224+ p .ipMap = ipMapping {}
225+ p .Begin , p .End = begin , end
226+ return nil
227+ }
228+
173229func (p * PortAllocator ) newPortMap () * portMap {
174230 defaultKey := getRangeKey (p .Begin , p .End )
175231 pm := & portMap {
0 commit comments