mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +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)
|
rc, err = dialer.Dial(network, server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newServer := ups.SwitchIf(server)
|
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)
|
qname, server, dialer.Addr(), err, newServer)
|
||||||
server = newServer
|
server = newServer
|
||||||
continue
|
continue
|
||||||
@ -179,7 +179,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
newServer := ups.SwitchIf(server)
|
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)
|
qname, server, dialer.Addr(), err, newServer)
|
||||||
|
|
||||||
server = 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/crypto v0.0.0-20200820211705-5c72a883971a
|
||||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728 // indirect
|
golang.org/x/net v0.0.0-20200927032502-5d4f70055728 // indirect
|
||||||
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c // 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
|
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 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-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-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-20200928112810-42b62fc93869 h1:6Zj8sAhgEtZaHYz4O/Grp2Gyh0FLb8a7sLJTanOG5QQ=
|
||||||
golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
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() {
|
func (s *TCPTun) ListenAndServe() {
|
||||||
l, err := net.Listen("tcp", s.addr)
|
l, err := net.Listen("tcp", s.addr)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +115,13 @@ func (f *Forwarder) Failures() uint32 {
|
|||||||
// IncFailures increase the failuer count by 1.
|
// IncFailures increase the failuer count by 1.
|
||||||
func (f *Forwarder) IncFailures() {
|
func (f *Forwarder) IncFailures() {
|
||||||
failures := atomic.AddUint32(&f.failures, 1)
|
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())
|
log.F("[forwarder] %s recorded %d failures, maxfailures: %d", f.addr, failures, f.MaxFailures())
|
||||||
|
|
||||||
if f.MaxFailures() != 0 && failures >= f.MaxFailures() && f.Enabled() {
|
if failures >= f.MaxFailures() && f.Enabled() {
|
||||||
log.F("[forwarder] %s reaches maxfailures %d", f.addr, f.MaxFailures())
|
|
||||||
f.Disable()
|
f.Disable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
|||||||
}
|
}
|
||||||
|
|
||||||
fwdr.Enable()
|
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)
|
website, readTime)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -46,10 +46,10 @@ func (*dpcpd) Run(args ...string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := server4.NewServer(
|
laddr := net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}
|
||||||
iface, &net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}, handleDHCP(ip, mask, pool))
|
server, err := server4.NewServer(iface, &laddr, handleDHCP(ip, mask, pool))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[dhcpd] error in server new: %s", err)
|
log.F("[dhcpd] error in server creation: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ func (*dpcpd) Run(args ...string) {
|
|||||||
|
|
||||||
func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
||||||
return func(conn net.PacketConn, peer net.Addr, m *dhcpv4.DHCPv4) {
|
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
|
var replyType dhcpv4.MessageType
|
||||||
switch mt := m.MessageType(); mt {
|
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 {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,20 +136,10 @@ func ifaceIPMask4(iface string) (net.IP, net.IPMask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
var ip net.IP
|
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||||
var mask net.IPMask
|
if ip4 := ipnet.IP.To4(); ip4 != nil {
|
||||||
|
return ip4, ipnet.Mask
|
||||||
switch v := addr.(type) {
|
}
|
||||||
case *net.IPNet:
|
|
||||||
ip = v.IP
|
|
||||||
mask = v.Mask
|
|
||||||
case *net.IPAddr:
|
|
||||||
ip = v.IP
|
|
||||||
mask = ip.DefaultMask()
|
|
||||||
}
|
|
||||||
|
|
||||||
if ip4 := ip.To4(); ip4 != nil {
|
|
||||||
return ip4, mask
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,38 +3,43 @@ package dhcpd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
lease time.Duration
|
|
||||||
items []*item
|
items []*item
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPool(lease time.Duration, ipStart, ipEnd net.IP) (*Pool, error) {
|
func NewPool(lease time.Duration, ipStart, ipEnd net.IP) (*Pool, error) {
|
||||||
items := make([]*item, 0)
|
items := make([]*item, 0)
|
||||||
var currentIp = ipStart.To4()
|
curip := ipStart.To4()
|
||||||
for bytes.Compare(currentIp, ipEnd.To4()) <= 0 {
|
for bytes.Compare(curip, ipEnd.To4()) <= 0 {
|
||||||
ip := make([]byte, 4)
|
ip := make([]byte, 4)
|
||||||
copy(ip, currentIp)
|
copy(ip, curip)
|
||||||
i := &item{
|
items = append(items, &item{lease: lease, ip: ip})
|
||||||
lease: lease,
|
curip[3]++
|
||||||
ip: ip,
|
|
||||||
}
|
|
||||||
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) {
|
func (p *Pool) AssignIP(mac net.HardwareAddr) (net.IP, error) {
|
||||||
var ip net.IP
|
var ip net.IP
|
||||||
for _, item := range p.items {
|
for _, item := range p.items {
|
||||||
if mac.String() == item.hardwareAddr.String() {
|
if bytes.Equal(mac, item.mac) {
|
||||||
return item.ip, nil
|
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 {
|
for _, item := range p.items {
|
||||||
if ip = item.take(mac); ip != nil {
|
if ip = item.take(mac); ip != nil {
|
||||||
return ip, nil
|
return ip, nil
|
||||||
@ -44,24 +49,23 @@ func (p *Pool) AssignIP(mac net.HardwareAddr) (net.IP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type item struct {
|
type item struct {
|
||||||
ip net.IP
|
taken bool
|
||||||
lease time.Duration
|
ip net.IP
|
||||||
taken bool
|
lease time.Duration
|
||||||
hardwareAddr net.HardwareAddr
|
mac net.HardwareAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *item) take(addr net.HardwareAddr) net.IP {
|
func (i *item) take(addr net.HardwareAddr) net.IP {
|
||||||
if i.taken {
|
if !i.taken {
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
i.taken = true
|
i.taken = true
|
||||||
go func() {
|
go func() {
|
||||||
timer := time.NewTimer(i.lease)
|
timer := time.NewTimer(i.lease)
|
||||||
<-timer.C
|
<-timer.C
|
||||||
i.hardwareAddr = nil
|
i.mac = nil
|
||||||
i.taken = false
|
i.taken = false
|
||||||
}()
|
}()
|
||||||
i.hardwareAddr = addr
|
i.mac = addr
|
||||||
return i.ip
|
return i.ip
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user