2021-11-10 13:46:52 -05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-12-16 17:41:17 -05:00
|
|
|
"aim-oscar/models"
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
2021-11-10 13:46:52 -05:00
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"net"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
2021-11-24 11:59:53 -05:00
|
|
|
|
2021-12-15 19:55:43 -05:00
|
|
|
"github.com/pkg/errors"
|
2021-12-16 17:41:17 -05:00
|
|
|
"github.com/uptrace/bun"
|
|
|
|
"github.com/uptrace/bun/dbfixture"
|
|
|
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
|
|
|
"github.com/uptrace/bun/driver/sqliteshim"
|
|
|
|
"github.com/uptrace/bun/extra/bundebug"
|
2021-11-10 13:46:52 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
SRV_HOST = ""
|
|
|
|
SRV_PORT = "5190"
|
|
|
|
SRV_ADDRESS = SRV_HOST + ":" + SRV_PORT
|
|
|
|
)
|
|
|
|
|
2021-11-16 16:44:29 -05:00
|
|
|
var services = make(map[uint16]Service)
|
2021-11-10 13:46:52 -05:00
|
|
|
|
2021-11-16 16:44:29 -05:00
|
|
|
func init() {
|
|
|
|
services[0x17] = &AuthorizationRegistrationService{}
|
2021-11-10 13:46:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2021-12-16 17:41:17 -05:00
|
|
|
// Set up the DB
|
|
|
|
sqldb, err := sql.Open(sqliteshim.ShimName, "file::memory:?cache=shared")
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
db := bun.NewDB(sqldb, sqlitedialect.New())
|
|
|
|
|
|
|
|
// Print all queries to stdout.
|
|
|
|
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
|
|
|
|
|
|
|
|
db.RegisterModel((*models.User)(nil))
|
|
|
|
|
|
|
|
fixture := dbfixture.New(db, dbfixture.WithRecreateTables())
|
|
|
|
err = fixture.Load(context.Background(), os.DirFS("models"), "fixtures.yml")
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2021-11-10 13:46:52 -05:00
|
|
|
listener, err := net.Listen("tcp", SRV_ADDRESS)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error listening: ", err.Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
defer listener.Close()
|
|
|
|
|
|
|
|
exitChan := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(exitChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT)
|
|
|
|
go func() {
|
|
|
|
<-exitChan
|
|
|
|
fmt.Println("Shutting down")
|
|
|
|
os.Exit(1)
|
|
|
|
}()
|
|
|
|
|
|
|
|
fmt.Println("OSCAR listening on " + SRV_ADDRESS)
|
|
|
|
for {
|
|
|
|
conn, err := listener.Accept()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error accepting connection: ", err.Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2021-12-15 19:55:43 -05:00
|
|
|
session := NewSession(conn)
|
2021-11-10 13:46:52 -05:00
|
|
|
log.Printf("Connection from %v", conn.RemoteAddr())
|
|
|
|
|
2021-12-16 17:41:17 -05:00
|
|
|
go handleTCPConnection(db, session, conn)
|
2021-11-10 13:46:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-16 17:41:17 -05:00
|
|
|
func handleTCPConnection(db *bun.DB, session *Session, conn net.Conn) {
|
2021-12-15 19:55:43 -05:00
|
|
|
// defer (func() {
|
|
|
|
// if err := recover(); err != nil {
|
|
|
|
// log.Printf("Error handling message: %+v\n", err.(error))
|
|
|
|
// }
|
|
|
|
// conn.Close()
|
|
|
|
// log.Printf("Closed connection to %v", conn.RemoteAddr())
|
|
|
|
// })()
|
2021-11-10 13:46:52 -05:00
|
|
|
|
|
|
|
buf := make([]byte, 1024)
|
|
|
|
for {
|
|
|
|
if !session.GreetedClient {
|
|
|
|
// send a hello
|
2021-12-16 18:37:27 -05:00
|
|
|
hello := NewFLAP(1)
|
2021-12-16 17:41:17 -05:00
|
|
|
hello.Data.Write([]byte{0, 0, 0, 1})
|
2021-11-16 16:44:29 -05:00
|
|
|
err := session.Send(hello)
|
|
|
|
panicIfError(err)
|
2021-11-10 13:46:52 -05:00
|
|
|
session.GreetedClient = true
|
|
|
|
}
|
|
|
|
|
|
|
|
n, err := conn.Read(buf)
|
|
|
|
if err != nil && err != io.EOF {
|
|
|
|
log.Println("Read Error: ", err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if n == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-12-15 19:55:43 -05:00
|
|
|
// Try to parse all of the FLAPs in the buffer if we have enough bytes to
|
|
|
|
// fill a FLAP header
|
|
|
|
for len(buf) >= 6 && buf[0] == 0x2a {
|
|
|
|
dataLength := Word(buf[4:6])
|
|
|
|
flapLength := int(dataLength) + 6
|
|
|
|
if len(buf) < flapLength {
|
|
|
|
log.Printf("not enough data, only %d bytes\n", len(buf))
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
flap := &FLAP{}
|
|
|
|
if err := flap.UnmarshalBinary(buf[:flapLength]); err != nil {
|
|
|
|
panicIfError(errors.Wrap(err, "could not unmarshal FLAP"))
|
|
|
|
}
|
|
|
|
buf = buf[flapLength:]
|
|
|
|
fmt.Printf("%v ->\n%+v\n", conn.RemoteAddr(), flap)
|
2021-12-16 17:41:17 -05:00
|
|
|
handleMessage(db, session, flap)
|
2021-12-15 19:55:43 -05:00
|
|
|
}
|
2021-11-10 13:46:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-16 17:41:17 -05:00
|
|
|
func handleMessage(db *bun.DB, session *Session, flap *FLAP) {
|
2021-12-15 19:55:43 -05:00
|
|
|
if flap.Header.Channel == 1 {
|
2021-11-10 13:46:52 -05:00
|
|
|
|
2021-12-15 19:55:43 -05:00
|
|
|
} else if flap.Header.Channel == 2 {
|
2021-11-16 16:44:29 -05:00
|
|
|
snac := &SNAC{}
|
2021-12-16 17:41:17 -05:00
|
|
|
err := snac.UnmarshalBinary(flap.Data.Bytes())
|
2021-11-16 16:44:29 -05:00
|
|
|
panicIfError(err)
|
2021-11-10 13:46:52 -05:00
|
|
|
|
2021-12-15 19:55:43 -05:00
|
|
|
fmt.Printf("%+v\n", snac)
|
2021-12-16 17:41:17 -05:00
|
|
|
if tlvs, err := UnmarshalTLVs(snac.Data.Bytes()); err == nil {
|
2021-12-15 19:55:43 -05:00
|
|
|
for _, tlv := range tlvs {
|
|
|
|
fmt.Printf("%+v\n", tlv)
|
|
|
|
}
|
|
|
|
} else {
|
2021-12-16 17:41:17 -05:00
|
|
|
fmt.Printf("%s\n\n", prettyBytes(snac.Data.Bytes()))
|
2021-12-15 19:55:43 -05:00
|
|
|
}
|
|
|
|
|
2021-11-16 16:44:29 -05:00
|
|
|
if service, ok := services[snac.Header.Family]; ok {
|
2021-12-16 17:41:17 -05:00
|
|
|
err = service.HandleSNAC(db, session, snac)
|
2021-12-15 19:55:43 -05:00
|
|
|
panicIfError(err)
|
2021-11-16 16:44:29 -05:00
|
|
|
}
|
|
|
|
}
|
2021-11-10 13:46:52 -05:00
|
|
|
}
|