package main import ( "crypto/aes" "crypto/cipher" "encoding/binary" "fmt" "net" "time" ) func serveConnection(conn net.Conn) { defer logPanic() defer conn.Close() fmt.Printf("Connection from %s\n", conn.RemoteAddr().String()) buf := make([]byte, 4) for { _, err := conn.Read(buf) errCheckPanic(err, "Connection failed with %s", conn.RemoteAddr().String()) id := binary.LittleEndian.Uint16(buf[:2]) board, ok := config.Boards[id] if !ok { fmt.Printf("Connection with ID %d is not registerd", id) break } board.LastSeen = time.Now() msglen := binary.LittleEndian.Uint16(buf[2:]) fmt.Printf("Connection from ID %d message length %d\n %x\n", id, msglen, buf) payload := make([]byte, msglen) _, err = conn.Read(payload) errCheckPanic(err, "Connection failed %s device #%d", conn.RemoteAddr().String(), id) fmt.Printf("Payload: %x\n", payload) message := make([]byte, msglen-16) block, err := aes.NewCipher(board.KEY) errCheckPanic(err, "Decryption failed %s device #%d", conn.RemoteAddr().String(), id) mode := cipher.NewCBCDecrypter(block, payload[:16]) mode.CryptBlocks(message, payload[16:]) fmt.Printf("Message: %s\n", string(message)) } } func serve(address string) { ln, err := net.Listen("tcp", address) errCheckExit(err,"Failed accept connection") defer ln.Close() fmt.Printf("Service socket ready at %s\n", address) for { conn, err := ln.Accept() errCheckExit(err,"Failed accept connection %s", conn.RemoteAddr().String()) go serveConnection(conn) } }