mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 09:25:41 +08:00
dhcpd: assign random ip
This commit is contained in:
parent
5b774cf90e
commit
de8c08c7b2
@ -155,7 +155,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (
|
||||
rc, err = dialer.Dial(network, server)
|
||||
if err != nil {
|
||||
newServer := ups.SwitchIf(server)
|
||||
log.F("[dns] error in resolving %s, failed to connect to server %v via %s: %v, switch to %s",
|
||||
log.F("[dns] error in resolving %s, failed to connect to server %v via %s: %v, next server: %s",
|
||||
qname, server, dialer.Addr(), err, newServer)
|
||||
server = newServer
|
||||
continue
|
||||
@ -179,7 +179,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (
|
||||
}
|
||||
|
||||
newServer := ups.SwitchIf(server)
|
||||
log.F("[dns] error in resolving %s, failed to exchange with server %v via %s: %v, switch to %s",
|
||||
log.F("[dns] error in resolving %s, failed to exchange with server %v via %s: %v, next server: %s",
|
||||
qname, server, dialer.Addr(), err, newServer)
|
||||
|
||||
server = newServer
|
||||
|
2
go.mod
2
go.mod
@ -13,7 +13,7 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728 // indirect
|
||||
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c // indirect
|
||||
golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346 // indirect
|
||||
golang.org/x/tools v0.0.0-20200928112810-42b62fc93869 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
)
|
||||
|
||||
|
4
go.sum
4
go.sum
@ -173,8 +173,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346 h1:hzJjkvxUIF3bSt+v8N5tBQNx/605vszZJ+3XsIamzZo=
|
||||
golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20200928112810-42b62fc93869 h1:6Zj8sAhgEtZaHYz4O/Grp2Gyh0FLb8a7sLJTanOG5QQ=
|
||||
golang.org/x/tools v0.0.0-20200928112810-42b62fc93869/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
|
@ -55,7 +55,7 @@ func NewTCPTunServer(s string, p proxy.Proxy) (proxy.Server, error) {
|
||||
func (s *TCPTun) ListenAndServe() {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.F("failed to listen on %s: %v", s.addr, err)
|
||||
log.F("[tcptun] failed to listen on %s: %v", s.addr, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -115,10 +115,13 @@ func (f *Forwarder) Failures() uint32 {
|
||||
// IncFailures increase the failuer count by 1.
|
||||
func (f *Forwarder) IncFailures() {
|
||||
failures := atomic.AddUint32(&f.failures, 1)
|
||||
if f.MaxFailures() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
log.F("[forwarder] %s recorded %d failures, maxfailures: %d", f.addr, failures, f.MaxFailures())
|
||||
|
||||
if f.MaxFailures() != 0 && failures >= f.MaxFailures() && f.Enabled() {
|
||||
log.F("[forwarder] %s reaches maxfailures %d", f.addr, f.MaxFailures())
|
||||
if failures >= f.MaxFailures() && f.Enabled() {
|
||||
f.Disable()
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
||||
}
|
||||
|
||||
fwdr.Enable()
|
||||
log.F("[check] %s(%d) -> %s, SUCCEEDED. connect time: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, SUCCESS. connect time: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, readTime)
|
||||
|
||||
return true
|
||||
|
@ -46,10 +46,10 @@ func (*dpcpd) Run(args ...string) {
|
||||
return
|
||||
}
|
||||
|
||||
server, err := server4.NewServer(
|
||||
iface, &net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}, handleDHCP(ip, mask, pool))
|
||||
laddr := net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}
|
||||
server, err := server4.NewServer(iface, &laddr, handleDHCP(ip, mask, pool))
|
||||
if err != nil {
|
||||
log.F("[dhcpd] error in server new: %s", err)
|
||||
log.F("[dhcpd] error in server creation: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ func (*dpcpd) Run(args ...string) {
|
||||
|
||||
func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
||||
return func(conn net.PacketConn, peer net.Addr, m *dhcpv4.DHCPv4) {
|
||||
log.F("[dpcpd] received request from client %v", m.ClientHWAddr)
|
||||
// log.F("[dpcpd] received request from client %v", m.ClientHWAddr)
|
||||
|
||||
var replyType dhcpv4.MessageType
|
||||
switch mt := m.MessageType(); mt {
|
||||
@ -99,7 +99,7 @@ func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
||||
}
|
||||
|
||||
if _, err := conn.WriteTo(reply.ToBytes(), peer); err != nil {
|
||||
log.F("[dpcpd] could not write %v: %s", reply, err)
|
||||
log.F("[dpcpd] could not write to client %s(%s): %s", peer, reply.ClientHWAddr, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -136,20 +136,10 @@ func ifaceIPMask4(iface string) (net.IP, net.IPMask) {
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
var mask net.IPMask
|
||||
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
mask = v.Mask
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
mask = ip.DefaultMask()
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ip4 := ipnet.IP.To4(); ip4 != nil {
|
||||
return ip4, ipnet.Mask
|
||||
}
|
||||
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
return ip4, mask
|
||||
}
|
||||
}
|
||||
|
@ -3,38 +3,43 @@ package dhcpd
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Pool struct {
|
||||
lease time.Duration
|
||||
items []*item
|
||||
}
|
||||
|
||||
func NewPool(lease time.Duration, ipStart, ipEnd net.IP) (*Pool, error) {
|
||||
items := make([]*item, 0)
|
||||
var currentIp = ipStart.To4()
|
||||
for bytes.Compare(currentIp, ipEnd.To4()) <= 0 {
|
||||
curip := ipStart.To4()
|
||||
for bytes.Compare(curip, ipEnd.To4()) <= 0 {
|
||||
ip := make([]byte, 4)
|
||||
copy(ip, currentIp)
|
||||
i := &item{
|
||||
lease: lease,
|
||||
ip: ip,
|
||||
copy(ip, curip)
|
||||
items = append(items, &item{lease: lease, ip: ip})
|
||||
curip[3]++
|
||||
}
|
||||
items = append(items, i)
|
||||
currentIp[3]++
|
||||
}
|
||||
return &Pool{lease: lease, items: items}, nil
|
||||
rand.Seed(time.Now().Unix())
|
||||
return &Pool{items: items}, nil
|
||||
}
|
||||
|
||||
func (p *Pool) AssignIP(mac net.HardwareAddr) (net.IP, error) {
|
||||
var ip net.IP
|
||||
for _, item := range p.items {
|
||||
if mac.String() == item.hardwareAddr.String() {
|
||||
if bytes.Equal(mac, item.mac) {
|
||||
return item.ip, nil
|
||||
}
|
||||
}
|
||||
|
||||
idx := rand.Intn(len(p.items))
|
||||
for _, item := range p.items[idx:] {
|
||||
if ip = item.take(mac); ip != nil {
|
||||
return ip, nil
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range p.items {
|
||||
if ip = item.take(mac); ip != nil {
|
||||
return ip, nil
|
||||
@ -44,24 +49,23 @@ func (p *Pool) AssignIP(mac net.HardwareAddr) (net.IP, error) {
|
||||
}
|
||||
|
||||
type item struct {
|
||||
taken bool
|
||||
ip net.IP
|
||||
lease time.Duration
|
||||
taken bool
|
||||
hardwareAddr net.HardwareAddr
|
||||
mac net.HardwareAddr
|
||||
}
|
||||
|
||||
func (i *item) take(addr net.HardwareAddr) net.IP {
|
||||
if i.taken {
|
||||
return nil
|
||||
} else {
|
||||
if !i.taken {
|
||||
i.taken = true
|
||||
go func() {
|
||||
timer := time.NewTimer(i.lease)
|
||||
<-timer.C
|
||||
i.hardwareAddr = nil
|
||||
i.mac = nil
|
||||
i.taken = false
|
||||
}()
|
||||
i.hardwareAddr = addr
|
||||
i.mac = addr
|
||||
return i.ip
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user