|
@@ -3,17 +3,36 @@ package portallocator
|
|
|
import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
+ "github.com/sirupsen/logrus"
|
|
|
"net"
|
|
|
"sync"
|
|
|
)
|
|
|
|
|
|
-const (
|
|
|
- // DefaultPortRangeStart indicates the first port in port range
|
|
|
- DefaultPortRangeStart = 49153
|
|
|
- // DefaultPortRangeEnd indicates the last port in port range
|
|
|
- DefaultPortRangeEnd = 65535
|
|
|
+var (
|
|
|
+ // defaultPortRangeStart indicates the first port in port range
|
|
|
+ defaultPortRangeStart = 49153
|
|
|
+ // defaultPortRangeEnd indicates the last port in port range
|
|
|
+ // consistent with default /proc/sys/net/ipv4/ip_local_port_range
|
|
|
+ // upper bound on linux
|
|
|
+ defaultPortRangeEnd = 60999
|
|
|
)
|
|
|
|
|
|
+func sanitizePortRange(start int, end int) (newStart, newEnd int, err error) {
|
|
|
+ if start > defaultPortRangeEnd || end < defaultPortRangeStart || start > end {
|
|
|
+ return 0, 0, fmt.Errorf("Request out allowed range [%v, %v]",
|
|
|
+ defaultPortRangeStart, defaultPortRangeEnd)
|
|
|
+ }
|
|
|
+ err = nil
|
|
|
+ newStart, newEnd = start, end
|
|
|
+ if start < defaultPortRangeStart {
|
|
|
+ newStart = defaultPortRangeStart
|
|
|
+ }
|
|
|
+ if end > defaultPortRangeEnd {
|
|
|
+ newEnd = defaultPortRangeEnd
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
type ipMapping map[string]protoMap
|
|
|
|
|
|
var (
|
|
@@ -92,11 +111,19 @@ func Get() *PortAllocator {
|
|
|
return instance
|
|
|
}
|
|
|
|
|
|
-func newInstance() *PortAllocator {
|
|
|
+func getDefaultPortRange() (int, int) {
|
|
|
start, end, err := getDynamicPortRange()
|
|
|
+ if err == nil {
|
|
|
+ start, end, err = sanitizePortRange(start, end)
|
|
|
+ }
|
|
|
if err != nil {
|
|
|
- start, end = DefaultPortRangeStart, DefaultPortRangeEnd
|
|
|
+ start, end = defaultPortRangeStart, defaultPortRangeEnd
|
|
|
}
|
|
|
+ return start, end
|
|
|
+}
|
|
|
+
|
|
|
+func newInstance() *PortAllocator {
|
|
|
+ start, end := getDefaultPortRange()
|
|
|
return &PortAllocator{
|
|
|
ipMap: ipMapping{},
|
|
|
Begin: start,
|
|
@@ -170,6 +197,35 @@ func (p *PortAllocator) ReleasePort(ip net.IP, proto string, port int) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+// SetPortRange sets dynamic port allocation range.
|
|
|
+// if both portBegin and portEnd are 0, the port range reverts to default
|
|
|
+// value. Otherwise they are sanitized against the default values to
|
|
|
+// ensure their validity.
|
|
|
+func (p *PortAllocator) SetPortRange(portBegin, portEnd int) error {
|
|
|
+ // if begin and end is zero, revert to default values
|
|
|
+ var begin, end int
|
|
|
+ var err error
|
|
|
+ if portBegin == 0 && portEnd == 0 {
|
|
|
+ begin, end = getDefaultPortRange()
|
|
|
+
|
|
|
+ } else {
|
|
|
+ begin, end, err = sanitizePortRange(portBegin, portEnd)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logrus.Debugf("Setting up port allocator to range %v-%v, current %v-%v",
|
|
|
+ begin, end, p.Begin, p.End)
|
|
|
+ p.mutex.Lock()
|
|
|
+ defer p.mutex.Unlock()
|
|
|
+ if p.Begin == begin && p.End == end {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ p.ipMap = ipMapping{}
|
|
|
+ p.Begin, p.End = begin, end
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func (p *PortAllocator) newPortMap() *portMap {
|
|
|
defaultKey := getRangeKey(p.Begin, p.End)
|
|
|
pm := &portMap{
|