stratux/network.go

159 wiersze
3.8 KiB
Go
Czysty Zwykły widok Historia

package main
import (
"io/ioutil"
2015-08-20 16:54:46 +00:00
"log"
"net"
2015-08-20 16:54:46 +00:00
"strconv"
"strings"
2015-08-20 17:06:40 +00:00
"sync"
2015-08-20 16:54:46 +00:00
"time"
)
type networkMessage struct {
msg []byte
msgType uint8
}
type networkConnection struct {
2015-08-21 09:08:34 +00:00
Conn *net.UDPConn
Ip string
Port uint32
Capability uint8
}
var messageQueue chan networkMessage
var outSockets map[string]networkConnection
var dhcpLeases map[string]string
2015-08-20 17:06:40 +00:00
var netMutex *sync.Mutex
const (
2015-08-24 00:49:24 +00:00
NETWORK_GDL90_STANDARD = 1
NETWORK_AHRS_FFSIM = 2
NETWORK_AHRS_GDL90 = 4
2015-08-21 23:05:05 +00:00
dhcp_lease_file = "/var/lib/dhcp/dhcpd.leases"
)
// Read the "dhcpd.leases" file and parse out IP/hostname.
func getDHCPLeases() (map[string]string, error) {
2015-08-21 23:05:05 +00:00
dat, err := ioutil.ReadFile(dhcp_lease_file)
ret := make(map[string]string)
if err != nil {
return ret, err
}
lines := strings.Split(string(dat), "\n")
open_block := false
block_ip := ""
for _, line := range lines {
spaced := strings.Split(line, " ")
if len(spaced) > 2 && spaced[0] == "lease" {
open_block = true
block_ip = spaced[1]
} else if open_block && len(spaced) >= 4 && spaced[2] == "client-hostname" {
hostname := strings.TrimRight(strings.TrimLeft(strings.Join(spaced[3:], " "), "\""), "\";")
ret[block_ip] = hostname
open_block = false
}
}
return ret, nil
}
func sendToAllConnectedClients(msg networkMessage) {
2015-08-20 17:06:40 +00:00
netMutex.Lock()
defer netMutex.Unlock()
for _, netconn := range outSockets {
2015-08-21 09:08:34 +00:00
if (netconn.Capability & msg.msgType) != 0 { // Check if this port is able to accept the type of message we're sending.
netconn.Conn.Write(msg.msg)
}
}
}
// Just returns the number of DHCP leases for now.
2015-08-22 01:00:43 +00:00
func getNetworkStats() uint {
ret := uint(len(dhcpLeases))
globalStatus.Connected_Users = ret
return ret
}
// See who has a DHCP lease and make a UDP connection to each of them.
func refreshConnectedClients() {
2015-08-20 17:06:40 +00:00
netMutex.Lock()
defer netMutex.Unlock()
validConnections := make(map[string]bool)
t, err := getDHCPLeases()
if err != nil {
log.Printf("getDHCPLeases(): %s\n", err.Error())
return
}
dhcpLeases = t
// Client connected that wasn't before.
for ip, hostname := range dhcpLeases {
for _, networkOutput := range globalSettings.NetworkOutputs {
2015-08-21 09:08:34 +00:00
ipAndPort := ip + ":" + strconv.Itoa(int(networkOutput.Port))
if _, ok := outSockets[ipAndPort]; !ok {
2015-08-21 09:08:34 +00:00
log.Printf("client connected: %s:%d (%s).\n", ip, networkOutput.Port, hostname)
addr, err := net.ResolveUDPAddr("udp", ipAndPort)
if err != nil {
log.Printf("ResolveUDPAddr(%s): %s\n", ipAndPort, err.Error())
continue
}
outConn, err := net.DialUDP("udp", nil, addr)
if err != nil {
log.Printf("DialUDP(%s): %s\n", ipAndPort, err.Error())
continue
}
2015-08-21 09:08:34 +00:00
outSockets[ipAndPort] = networkConnection{outConn, ip, networkOutput.Port, networkOutput.Capability}
}
validConnections[ipAndPort] = true
}
}
// Client that was connected before that isn't.
for ipAndPort, conn := range outSockets {
if _, ok := validConnections[ipAndPort]; !ok {
log.Printf("removed connection %s.\n", ipAndPort)
2015-08-21 09:08:34 +00:00
conn.Conn.Close()
delete(outSockets, ipAndPort)
}
}
}
func messageQueueSender() {
2015-08-22 01:00:43 +00:00
secondTimer := time.NewTicker(5 * time.Second)
for {
select {
2015-08-20 16:54:46 +00:00
case msg := <-messageQueue:
sendToAllConnectedClients(msg)
case <-secondTimer.C:
getNetworkStats()
}
}
}
func sendMsg(msg []byte, msgType uint8) {
messageQueue <- networkMessage{msg, msgType}
}
func sendGDL90(msg []byte) {
2015-08-24 00:49:24 +00:00
sendMsg(msg, NETWORK_GDL90_STANDARD)
}
2015-08-21 23:05:05 +00:00
func monitorDHCPLeases() {
//TODO: inotify or dhcp event hook.
timer := time.NewTicker(30 * time.Second)
2015-08-21 23:05:05 +00:00
for {
select {
case <-timer.C:
2015-08-21 23:05:05 +00:00
refreshConnectedClients()
}
}
}
func initNetwork() {
messageQueue = make(chan networkMessage, 1024) // Buffered channel, 1024 messages.
outSockets = make(map[string]networkConnection)
2015-08-20 17:06:40 +00:00
netMutex = &sync.Mutex{}
refreshConnectedClients()
2015-08-21 23:05:05 +00:00
go monitorDHCPLeases()
go messageQueueSender()
2015-08-20 16:54:46 +00:00
}