database
This commit is contained in:
		
							parent
							
								
									39ff9a43b0
								
							
						
					
					
						commit
						3b98fb36cb
					
				|  | @ -51,17 +51,17 @@ func (msg *SocketMSG) Marshal() ([]byte, error) { | ||||||
| 	pos += 4 | 	pos += 4 | ||||||
| 
 | 
 | ||||||
| 	if msg.Types.Is(SocketMSGTypeClient) { | 	if msg.Types.Is(SocketMSGTypeClient) { | ||||||
| 		obj[pos] = msg.Client.Addr.HardwareAddr[0] | 		obj[pos] = msg.Client.Addr[0] | ||||||
| 		pos++ | 		pos++ | ||||||
| 		obj[pos] = msg.Client.Addr.HardwareAddr[1] | 		obj[pos] = msg.Client.Addr[1] | ||||||
| 		pos++ | 		pos++ | ||||||
| 		obj[pos] = msg.Client.Addr.HardwareAddr[2] | 		obj[pos] = msg.Client.Addr[2] | ||||||
| 		pos++ | 		pos++ | ||||||
| 		obj[pos] = msg.Client.Addr.HardwareAddr[3] | 		obj[pos] = msg.Client.Addr[3] | ||||||
| 		pos++ | 		pos++ | ||||||
| 		obj[pos] = msg.Client.Addr.HardwareAddr[4] | 		obj[pos] = msg.Client.Addr[4] | ||||||
| 		pos++ | 		pos++ | ||||||
| 		obj[pos] = msg.Client.Addr.HardwareAddr[5] | 		obj[pos] = msg.Client.Addr[5] | ||||||
| 		pos++ | 		pos++ | ||||||
| 		binary.BigEndian.PutUint32(obj[pos:(pos+4)], uint32(msg.Client.Time.Unix())) | 		binary.BigEndian.PutUint32(obj[pos:(pos+4)], uint32(msg.Client.Time.Unix())) | ||||||
| 		pos += 4 | 		pos += 4 | ||||||
|  | @ -100,7 +100,7 @@ func (msg *SocketMSG) Unmarshal(obj []byte) error { | ||||||
| 
 | 
 | ||||||
| 	if msg.Types.Is(SocketMSGTypeClient) { | 	if msg.Types.Is(SocketMSGTypeClient) { | ||||||
| 		msg.Client = &WifiClient{ | 		msg.Client = &WifiClient{ | ||||||
| 			Addr:           data.HardwareAddr{HardwareAddr: obj[pos:(pos + 6)]}, | 			Addr:           data.HardwareAddr(obj[pos:(pos + 6)]), | ||||||
| 			Time:           time.Unix(int64(binary.BigEndian.Uint32(obj[(pos+6):(pos+10)])), 0), | 			Time:           time.Unix(int64(binary.BigEndian.Uint32(obj[(pos+6):(pos+10)])), 0), | ||||||
| 			TryProbe:       binary.BigEndian.Uint16(obj[(pos + 10):(pos + 12)]), | 			TryProbe:       binary.BigEndian.Uint16(obj[(pos + 10):(pos + 12)]), | ||||||
| 			TryAuth:        binary.BigEndian.Uint16(obj[(pos + 12):(pos + 14)]), | 			TryAuth:        binary.BigEndian.Uint16(obj[(pos + 12):(pos + 14)]), | ||||||
|  |  | ||||||
|  | @ -6,18 +6,18 @@ import ( | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"syscall" | 	"syscall" | ||||||
| 
 | 
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
| 	"dev.sum7.eu/genofire/golang-lib/file" | 	"dev.sum7.eu/genofire/golang-lib/file" | ||||||
| 	"github.com/bdlm/log" | 	"github.com/bdlm/log" | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 
 | 
 | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/controller" | 	"dev.sum7.eu/genofire/wifictld-analyzer/controller" | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/database" |  | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/web" | 	"dev.sum7.eu/genofire/wifictld-analyzer/web" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type ControllerConfig struct { | type ControllerConfig struct { | ||||||
| 	Database   string                 `toml:"database"` | 	Database   database.Config        `toml:"database"` | ||||||
| 	Answer     bool                   `toml:"answer"` | 	Answer     bool                   `toml:"answer"` | ||||||
| 	Webserver  *web.Config            `toml:"webserver"` | 	Webserver  *web.Config            `toml:"webserver"` | ||||||
| 	Interfaces []*capture.IFaceConfig `toml:"interfaces"` | 	Interfaces []*capture.IFaceConfig `toml:"interfaces"` | ||||||
|  | @ -34,9 +34,12 @@ var controllerCmd = &cobra.Command{ | ||||||
| 
 | 
 | ||||||
| 		file.ReadTOML(args[0], config) | 		file.ReadTOML(args[0], config) | ||||||
| 
 | 
 | ||||||
| 		db := database.NewDB(config.Database) | 		if err := database.Open(config.Database); err != nil { | ||||||
|  | 			log.Panicf("no database connection: %s", err) | ||||||
|  | 		} | ||||||
|  | 		defer database.Close() | ||||||
| 
 | 
 | ||||||
| 		ctr := controller.NewController(db) | 		ctr := controller.NewController() | ||||||
| 		defer ctr.Close() | 		defer ctr.Close() | ||||||
| 
 | 
 | ||||||
| 		var handlers []capture.Handler | 		var handlers []capture.Handler | ||||||
|  |  | ||||||
|  | @ -1,6 +1,11 @@ | ||||||
| database = "/tmp/wifictld.json" |  | ||||||
| answer = false | answer = false | ||||||
| 
 | 
 | ||||||
|  | [database] | ||||||
|  | type = "sqlite3" | ||||||
|  | logging = true | ||||||
|  | connection = "file:/tmp/wifictld.db" | ||||||
|  | # For Master-Slave cluster | ||||||
|  | # read_connection = "" | ||||||
| 
 | 
 | ||||||
| [webserver] | [webserver] | ||||||
| enable  = true | enable  = true | ||||||
|  |  | ||||||
|  | @ -2,24 +2,38 @@ package controller | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"net" | 	"net" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
| 	// "github.com/bdlm/log"
 | 	// "github.com/bdlm/log"
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
| 
 | 
 | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | ||||||
|  | 	"dev.sum7.eu/genofire/wifictld-analyzer/data" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func (c *Controller) Handler(addr *net.UDPAddr, msg *capture.SocketMSG) (*capture.SocketMSG, error) { | func (c *Controller) Handler(addr *net.UDPAddr, msg *capture.SocketMSG) (*capture.SocketMSG, error) { | ||||||
| 	ignore := false | 	ignore := false | ||||||
| 	if msg.Types.Is(capture.SocketMSGTypeClient) && msg.Client != nil { | 	if msg.Types.Is(capture.SocketMSGTypeClient) && msg.Client != nil { | ||||||
| 		ignore = c.db.LearnClient(addr.IP, msg.Client) | 		ignore = c.LearnClient(addr.IP, msg.Client) | ||||||
| 	} | 	} | ||||||
| 	if !msg.Types.Is(capture.SocketMSGTypeRequest) { | 	if !msg.Types.Is(capture.SocketMSGTypeRequest) { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	client := &data.Client{Addr: msg.Client.Addr} | ||||||
|  | 
 | ||||||
|  | 	if result := database.Read.Select([]string{"try_probe", "try_auth"}).First(client); result.Error != nil { | ||||||
|  | 		return nil, result.Error | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	msg = &capture.SocketMSG{ | 	msg = &capture.SocketMSG{ | ||||||
| 		Types: (capture.SocketMSGTypeResponse | capture.SocketMSGTypeClient), | 		Types: (capture.SocketMSGTypeResponse | capture.SocketMSGTypeClient), | ||||||
| 		Client: c.db.GetClient(msg.Client.Addr), | 		Client: &capture.WifiClient{ | ||||||
|  | 			Addr:     msg.Client.Addr, | ||||||
|  | 			Time:     time.Now(), | ||||||
|  | 			TryProbe: client.TryProbe, | ||||||
|  | 			TryAuth:  client.TryAuth, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !ignore { | 	if !ignore { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,57 @@ | ||||||
|  | package controller | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	// "github.com/bdlm/log"
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
|  | 
 | ||||||
|  | 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | ||||||
|  | 	"dev.sum7.eu/genofire/wifictld-analyzer/data" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func (c *Controller) LearnClient(apIP net.IP, clientWifictl *capture.WifiClient) bool { | ||||||
|  | 	ret := false | ||||||
|  | 
 | ||||||
|  | 	// learn ap
 | ||||||
|  | 	ap := &data.AP{ | ||||||
|  | 		IP:       apIP, | ||||||
|  | 		Lastseen: time.Now(), | ||||||
|  | 	} | ||||||
|  | 	result := database.Read.First(ap) | ||||||
|  | 	if result.RowsAffected > 0 { | ||||||
|  | 		database.Write.Save(ap) | ||||||
|  | 	} else { | ||||||
|  | 		database.Write.Create(ap) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// learn client
 | ||||||
|  | 	client := &data.Client{ | ||||||
|  | 		Addr:           clientWifictl.Addr, | ||||||
|  | 		Lastseen:       time.Now(), | ||||||
|  | 		APAddr:         apIP, | ||||||
|  | 		Connected:      clientWifictl.Connected, | ||||||
|  | 		SignalLowFreq:  clientWifictl.SignalLowFreq, | ||||||
|  | 		SignalHighFreq: clientWifictl.SignalHighFreq, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	database.Write.FirstOrCreate(client) | ||||||
|  | 
 | ||||||
|  | 	if clientWifictl.TryAuth > client.TryAuth { | ||||||
|  | 		client.TryAuth = clientWifictl.TryAuth | ||||||
|  | 	} | ||||||
|  | 	if clientWifictl.TryProbe > client.TryProbe { | ||||||
|  | 		client.TryProbe = clientWifictl.TryProbe | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if client.FreqHighest < clientWifictl.FreqHighest { | ||||||
|  | 		ret = (client.FreqHighest != 0) | ||||||
|  | 		client.FreqHighest = clientWifictl.FreqHighest | ||||||
|  | 	} | ||||||
|  | 	if clientWifictl.Authed { | ||||||
|  | 		client.Authed = clientWifictl.Authed | ||||||
|  | 	} | ||||||
|  | 	database.Write.Save(client) | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | @ -4,23 +4,22 @@ import ( | ||||||
| 	"net" | 	"net" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
| 	"github.com/bdlm/log" | 	"github.com/bdlm/log" | ||||||
| 
 | 
 | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/database" | 	"dev.sum7.eu/genofire/wifictld-analyzer/data" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Controller struct { | type Controller struct { | ||||||
| 	SendTo func(addr *net.UDPAddr, msg *capture.SocketMSG) | 	SendTo func(addr *net.UDPAddr, msg *capture.SocketMSG) | ||||||
| 	Send   func(msg *capture.SocketMSG) | 	Send   func(msg *capture.SocketMSG) | ||||||
| 	db     *database.DB |  | ||||||
| 	ticker *time.Ticker | 	ticker *time.Ticker | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewController(db *database.DB) *Controller { | func NewController() *Controller { | ||||||
| 	ctl := &Controller{ | 	ctl := &Controller{ | ||||||
| 		ticker: time.NewTicker(time.Minute), | 		ticker: time.NewTicker(time.Minute), | ||||||
| 		db:     db, |  | ||||||
| 	} | 	} | ||||||
| 	go ctl.Repeated() | 	go ctl.Repeated() | ||||||
| 	return ctl | 	return ctl | ||||||
|  | @ -31,7 +30,12 @@ func (c *Controller) Close() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Controller) Repeated() { | func (c *Controller) Repeated() { | ||||||
|  | 	aps := 0 | ||||||
|  | 	clients := 0 | ||||||
|  | 
 | ||||||
| 	for range c.ticker.C { | 	for range c.ticker.C { | ||||||
| 		log.Debugf("lerned: %d APs, %d Clients", len(c.db.APs), len(c.db.Clients)) | 		database.Read.Model(&data.AP{}).Count(&aps) | ||||||
|  | 		database.Read.Model(&data.Client{}).Count(&clients) | ||||||
|  | 		log.Debugf("learned: %d APs, %d Clients", aps, clients) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | package data | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | 
 | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type AP struct { | ||||||
|  | 	IP       net.IP    `json:"ip" gorm:"PRIMARY_KEY"` | ||||||
|  | 	Lastseen time.Time `json:"lastseen"` | ||||||
|  | 	Clients  []Client  `gorm:"foreignkey:APAddr" json:"-"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Function to initialize the database
 | ||||||
|  | func init() { | ||||||
|  | 	database.AddModel(&AP{}) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | package data | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Client struct { | ||||||
|  | 	Addr           HardwareAddr `gorm:"PRIMARY_KEY" json:"addr"` | ||||||
|  | 	APAddr         net.IP       `gorm:"column:ap" json:"ap"` | ||||||
|  | 	TryProbe       uint16       `json:"try_probe"` | ||||||
|  | 	TryAuth        uint16       `json:"try_auth"` | ||||||
|  | 	Connected      bool         `json:"connected"` | ||||||
|  | 	Authed         bool         `json:"authed"` | ||||||
|  | 	FreqHighest    uint16       `json:"freq_highest"` | ||||||
|  | 	SignalLowFreq  int16        `json:"signal_low_freq"` | ||||||
|  | 	SignalHighFreq int16        `json:"signal_high_freq"` | ||||||
|  | 	Lastseen       time.Time    `json:"lastseen"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Function to initialize the database
 | ||||||
|  | func init() { | ||||||
|  | 	database.AddModel(&Client{}) | ||||||
|  | } | ||||||
|  | @ -2,7 +2,12 @@ package data | ||||||
| 
 | 
 | ||||||
| import "net" | import "net" | ||||||
| 
 | 
 | ||||||
| type HardwareAddr struct{ net.HardwareAddr } | type HardwareAddr net.HardwareAddr | ||||||
|  | 
 | ||||||
|  | //MarshalJSON to bytearray
 | ||||||
|  | func (a HardwareAddr) String() string { | ||||||
|  | 	return net.HardwareAddr(a).String() | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| //MarshalJSON to bytearray
 | //MarshalJSON to bytearray
 | ||||||
| func (a HardwareAddr) MarshalText() ([]byte, error) { | func (a HardwareAddr) MarshalText() ([]byte, error) { | ||||||
|  | @ -10,7 +15,11 @@ func (a HardwareAddr) MarshalText() ([]byte, error) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UnmarshalJSON from bytearray
 | // UnmarshalJSON from bytearray
 | ||||||
| func (a HardwareAddr) UnmarshalText(data []byte) (err error) { | func (a HardwareAddr) UnmarshalText(data []byte) error { | ||||||
| 	a.HardwareAddr, err = net.ParseMAC(string(data)) | 	b, err := net.ParseMAC(string(data)) | ||||||
| 	return | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	a = HardwareAddr(b) | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,22 +0,0 @@ | ||||||
| package database |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"net" |  | ||||||
| 
 |  | ||||||
| 	"github.com/FreifunkBremen/yanic/lib/jsontime" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type AP struct { |  | ||||||
| 	IP       *net.IP       `json:"ip"` |  | ||||||
| 	Lastseen jsontime.Time `json:"lastseen"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (db *DB) GetClients(ap *AP) []*Client { |  | ||||||
| 	var clients []*Client |  | ||||||
| 	for _, client := range db.Clients { |  | ||||||
| 		if client.AP == ap { |  | ||||||
| 			clients = append(clients, client) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return clients |  | ||||||
| } |  | ||||||
|  | @ -1,84 +0,0 @@ | ||||||
| package database |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"net" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	// "github.com/bdlm/log"
 |  | ||||||
| 	"github.com/FreifunkBremen/yanic/lib/jsontime" |  | ||||||
| 
 |  | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" |  | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/data" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type Client struct { |  | ||||||
| 	AP             *AP               `json:"-"` |  | ||||||
| 	APAddr         string            `json:"ap"` |  | ||||||
| 	Addr           data.HardwareAddr `json:"-"` |  | ||||||
| 	TryProbe       uint16            `json:"try_probe"` |  | ||||||
| 	TryAuth        uint16            `json:"try_auth"` |  | ||||||
| 	Connected      bool              `json:"connected"` |  | ||||||
| 	Authed         bool              `json:"authed"` |  | ||||||
| 	FreqHighest    uint16            `json:"freq_highest"` |  | ||||||
| 	SignalLowFreq  int16             `json:"signal_low_freq"` |  | ||||||
| 	SignalHighFreq int16             `json:"signal_high_freq"` |  | ||||||
| 	Lastseen       jsontime.Time     `json:"lastseen"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (db *DB) LearnClient(apIP net.IP, clientWifictl *capture.WifiClient) bool { |  | ||||||
| 	ret := false |  | ||||||
| 
 |  | ||||||
| 	// learn ap
 |  | ||||||
| 	apAddr := apIP.String() |  | ||||||
| 	ap, ok := db.APs[apAddr] |  | ||||||
| 	if !ok { |  | ||||||
| 		ap = &AP{} |  | ||||||
| 		db.APs[apAddr] = ap |  | ||||||
| 	} |  | ||||||
| 	ap.IP = &apIP |  | ||||||
| 	ap.Lastseen = jsontime.Now() |  | ||||||
| 
 |  | ||||||
| 	// learn client
 |  | ||||||
| 	clientAddr := clientWifictl.Addr.String() |  | ||||||
| 	client, ok := db.Clients[clientAddr] |  | ||||||
| 	if !ok { |  | ||||||
| 		client = &Client{ |  | ||||||
| 			Addr: clientWifictl.Addr, |  | ||||||
| 		} |  | ||||||
| 		db.Clients[clientAddr] = client |  | ||||||
| 	} |  | ||||||
| 	client.Lastseen = jsontime.Now() |  | ||||||
| 	client.AP = ap |  | ||||||
| 	client.APAddr = apAddr |  | ||||||
| 	client.Connected = clientWifictl.Connected |  | ||||||
| 	client.SignalLowFreq = clientWifictl.SignalLowFreq |  | ||||||
| 	client.SignalHighFreq = clientWifictl.SignalHighFreq |  | ||||||
| 
 |  | ||||||
| 	if clientWifictl.TryAuth > client.TryAuth { |  | ||||||
| 		client.TryAuth = clientWifictl.TryAuth |  | ||||||
| 	} |  | ||||||
| 	if clientWifictl.TryProbe > client.TryProbe { |  | ||||||
| 		client.TryProbe = clientWifictl.TryProbe |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if client.FreqHighest < clientWifictl.FreqHighest { |  | ||||||
| 		ret = (client.FreqHighest != 0) |  | ||||||
| 		client.FreqHighest = clientWifictl.FreqHighest |  | ||||||
| 	} |  | ||||||
| 	if clientWifictl.Authed { |  | ||||||
| 		client.Authed = clientWifictl.Authed |  | ||||||
| 	} |  | ||||||
| 	return ret |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (db *DB) GetClient(addr data.HardwareAddr) *capture.WifiClient { |  | ||||||
| 	client, ok := db.Clients[addr.String()] |  | ||||||
| 	wClient := &capture.WifiClient{ |  | ||||||
| 		Addr: addr, |  | ||||||
| 		Time: time.Now(), |  | ||||||
| 	} |  | ||||||
| 	if ok { |  | ||||||
| 		wClient.TryProbe = client.TryProbe |  | ||||||
| 	} |  | ||||||
| 	return wClient |  | ||||||
| } |  | ||||||
|  | @ -1,47 +0,0 @@ | ||||||
| package database |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"github.com/bdlm/log" |  | ||||||
| 
 |  | ||||||
| 	"dev.sum7.eu/genofire/golang-lib/file" |  | ||||||
| 	"dev.sum7.eu/genofire/golang-lib/worker" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type DB struct { |  | ||||||
| 	Clients map[string]*Client `json:"client"` |  | ||||||
| 	APs     map[string]*AP     `json:"ap"` |  | ||||||
| 	worker  *worker.Worker |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewDB(path string) *DB { |  | ||||||
| 	db := &DB{ |  | ||||||
| 		Clients: make(map[string]*Client), |  | ||||||
| 		APs:     make(map[string]*AP), |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	file.ReadJSON(path, db) |  | ||||||
| 
 |  | ||||||
| 	for addr, client := range db.Clients { |  | ||||||
| 		client.Addr.UnmarshalText([]byte(addr)) |  | ||||||
| 		if ap, ok := db.APs[client.APAddr]; ok { |  | ||||||
| 			client.AP = ap |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	db.worker = worker.NewWorker(time.Minute, func() { |  | ||||||
| 		file.SaveJSON(path, db) |  | ||||||
| 		log.Debug("save db state") |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	db.worker.Start() |  | ||||||
| 
 |  | ||||||
| 	return db |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (db *DB) Close() { |  | ||||||
| 	if db.worker != nil { |  | ||||||
| 		db.worker.Close() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| package database |  | ||||||
|  | @ -7,9 +7,12 @@ import ( | ||||||
| 	"github.com/NYTimes/gziphandler" | 	"github.com/NYTimes/gziphandler" | ||||||
| 	"github.com/bdlm/log" | 	"github.com/bdlm/log" | ||||||
| 
 | 
 | ||||||
|  | 	"dev.sum7.eu/genofire/golang-lib/database" | ||||||
|  | 	lib "dev.sum7.eu/genofire/golang-lib/http" | ||||||
| 	"dev.sum7.eu/genofire/golang-lib/websocket" | 	"dev.sum7.eu/genofire/golang-lib/websocket" | ||||||
| 
 | 
 | ||||||
| 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | 	"dev.sum7.eu/genofire/wifictld-analyzer/capture" | ||||||
|  | 	"dev.sum7.eu/genofire/wifictld-analyzer/data" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Server struct { | type Server struct { | ||||||
|  | @ -22,6 +25,26 @@ func New(config *Config) *Server { | ||||||
| 	ws := websocket.NewWebsocketHandlerService() | 	ws := websocket.NewWebsocketHandlerService() | ||||||
| 	ws.Listen("/ws") | 	ws.Listen("/ws") | ||||||
| 
 | 
 | ||||||
|  | 	http.HandleFunc("/data.json", func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		type dataResponse struct { | ||||||
|  | 			APs     []data.AP     `json:"aps"` | ||||||
|  | 			Clients []data.Client `json:"clients"` | ||||||
|  | 		} | ||||||
|  | 		data := &dataResponse{} | ||||||
|  | 		if result := database.Read.Find(&data.APs); result.Error != nil { | ||||||
|  | 			log.WithField("error", result.Error.Error()).Warn("not possible to read APs") | ||||||
|  | 			http.Error(w, "not possible to read APs", http.StatusNotFound) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		if result := database.Read.Find(&data.Clients); result.Error != nil { | ||||||
|  | 			log.WithField("error", result.Error.Error()).Warn("not possible to read Clients") | ||||||
|  | 			http.Error(w, "not possible to read Clients", http.StatusNotFound) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		lib.Write(w, data) | ||||||
|  | 		log.Info("fetch data") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
| 	http.Handle("/", gziphandler.GzipHandler(http.FileServer(http.Dir(config.Webroot)))) | 	http.Handle("/", gziphandler.GzipHandler(http.FileServer(http.Dir(config.Webroot)))) | ||||||
| 	return &Server{ | 	return &Server{ | ||||||
| 		web: &http.Server{ | 		web: &http.Server{ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue