Commit 62e1cca9 authored by bletest's avatar bletest
Browse files

update discovery

parent ecb28ed8
No related merge requests found
Showing with 68 additions and 5 deletions
+68 -5
......@@ -18,8 +18,10 @@ import (
"encoding/xml"
"fmt"
"log"
"net"
"net/http"
"net/url"
"sync"
"time"
"golang.org/x/net/html/charset"
......@@ -57,6 +59,28 @@ type MaybeRootDevice struct {
Err error
}
func GetPrivateIPs() ([]net.IPNet, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
var IPsList []net.IPNet
_, private24BitBlock, _ := net.ParseCIDR("10.0.0.0/8")
_, private20BitBlock, _ := net.ParseCIDR("172.16.0.0/12")
_, private16BitBlock, _ := net.ParseCIDR("192.168.0.0/16")
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok {
if ipnet.IP.To4() != nil && !ipnet.IP.IsLoopback() && !ipnet.IP.IsLinkLocalUnicast() && !ipnet.IP.IsLinkLocalMulticast() {
if private24BitBlock.Contains(ipnet.IP) || private20BitBlock.Contains(ipnet.IP) || private16BitBlock.Contains(ipnet.IP) {
IPsList = append(IPsList, *ipnet)
}
}
}
}
return IPsList, nil
}
// DiscoverDevices attempts to find targets of the given type. This is
// typically the entry-point for this package. searchTarget is typically a URN
// in the form "urn:schemas-upnp-org:device:..." or
......@@ -64,14 +88,53 @@ type MaybeRootDevice struct {
// while attempting to send the query. An error or RootDevice is returned for
// each discovered RootDevice.
func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
httpu, err := httpu.NewHTTPUClient()
var wg sync.WaitGroup
ifaces, err := GetPrivateIPs()
if err != nil {
return nil, err
}
defer httpu.Close()
responses, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 3, 3)
if err != nil {
return nil, err
errChan := make(chan error)
resultChan := make(chan []*http.Response)
doneChan := make(chan struct{})
for _, ip := range ifaces {
wg.Add(1)
go func(ip net.IPNet) {
defer wg.Done()
httpu, err := httpu.NewHTTPUClientAddr(ip.IP.String())
if err != nil {
errChan <- err
return
}
respon, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 2, 2)
if err != nil {
errChan <- err
return
}
resultChan <- respon
defer httpu.Close()
}(ip)
}
go func() {
wg.Wait()
doneChan <- struct{}{}
}()
responses := make([]*http.Response, 0)
L:
for {
select {
case err := <-errChan:
return nil, err
case res := <-resultChan:
responses = append(responses, res...)
case <-doneChan:
break L
}
}
for _, resp := range responses {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment