mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-11-21 12:09:48 -05:00
Explore rewriting Auth server in Go
This commit is contained in:
parent
f2ab2ced48
commit
27aea95084
4 changed files with 170 additions and 0 deletions
3
go.mod
Normal file
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
|||
module aim-oscar
|
||||
|
||||
go 1.16
|
122
main.go
Normal file
122
main.go
Normal file
|
@ -0,0 +1,122 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
SRV_HOST = ""
|
||||
SRV_PORT = "5190"
|
||||
SRV_ADDRESS = SRV_HOST + ":" + SRV_PORT
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
Conn net.Conn
|
||||
GreetedClient bool
|
||||
}
|
||||
|
||||
func NewSession(conn net.Conn) *Session {
|
||||
return &Session{
|
||||
Conn: conn,
|
||||
GreetedClient: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) Send(bytes []byte) {
|
||||
fmt.Printf("-> %v\n%s\n\n", s.Conn.RemoteAddr(), prettyBytes(bytes))
|
||||
s.Conn.Write(bytes)
|
||||
}
|
||||
|
||||
func main() {
|
||||
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)
|
||||
}
|
||||
|
||||
ctx := context.WithValue(context.Background(), "session", NewSession(conn))
|
||||
log.Printf("Connection from %v", conn.RemoteAddr())
|
||||
|
||||
go handleTCPConnection(ctx, conn)
|
||||
}
|
||||
}
|
||||
|
||||
func handleTCPConnection(ctx context.Context, conn net.Conn) {
|
||||
defer (func() {
|
||||
recover()
|
||||
conn.Close()
|
||||
log.Printf("Closed connection to %v", conn.RemoteAddr())
|
||||
})()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
session := ctx.Value("session").(*Session)
|
||||
if !session.GreetedClient {
|
||||
// send a hello
|
||||
hello := []byte{0x2a, 1, 0, 0, 0, 4, 0, 0, 0, 1}
|
||||
session.Send(hello)
|
||||
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
|
||||
}
|
||||
|
||||
fmt.Printf("%v ->\n%s\n\n", conn.RemoteAddr(), prettyBytes(buf[:n]))
|
||||
handleMessage(ctx, buf[:n])
|
||||
}
|
||||
}
|
||||
|
||||
func handleMessage(ctx context.Context, buf []byte) {
|
||||
messageBuf := bytes.NewBuffer(buf)
|
||||
|
||||
start, err := messageBuf.ReadByte()
|
||||
panicIfError(err)
|
||||
if start != 0x2a {
|
||||
log.Println("FLAP message missing leading 0x2a")
|
||||
return
|
||||
}
|
||||
|
||||
// Start parsing FLAP header
|
||||
channel := mustReadNBytes(messageBuf, 1)[0]
|
||||
log.Println("Message for channel: ", channel)
|
||||
|
||||
datagramSeqNum := mustReadNBytes(messageBuf, 2)
|
||||
log.Println("Datagram Sequence Number: ", binary.BigEndian.Uint16(datagramSeqNum))
|
||||
|
||||
dataLength := mustReadNBytes(messageBuf, 2)
|
||||
log.Println("Data Length: ", binary.BigEndian.Uint16(dataLength))
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev:tsc": "tsc --watch",
|
||||
"dev:nodemon:auth-go": "nodemon --watch ./ -e go --delay 200ms --exec 'go run *.go || exit 1' --signal SIGTERM",
|
||||
"dev:nodemon:auth": "nodemon --watch ./dist --delay 200ms dist/src/main-auth.js",
|
||||
"dev:nodemon:chat": "nodemon --watch ./dist --delay 200ms dist/src/main-chat.js",
|
||||
"start": "tsc && node ./dist/index.js"
|
||||
|
|
44
util.go
Normal file
44
util.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func prettyBytes(bytes []byte) string {
|
||||
res := ""
|
||||
hexStr := hex.EncodeToString(bytes)
|
||||
for i := 0; i < len(hexStr); i++ {
|
||||
if i > 0 && i%16 == 0 {
|
||||
res += "\n"
|
||||
} else if i > 0 && i%2 == 0 {
|
||||
res += " "
|
||||
}
|
||||
res += string(hexStr[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func printBytes(bytes []byte) {
|
||||
fmt.Printf("%s\n", prettyBytes(bytes))
|
||||
}
|
||||
|
||||
func panicIfError(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func readNBytes(buf *bytes.Buffer, n int) ([]byte, error) {
|
||||
res := make([]byte, n)
|
||||
_, err := io.ReadFull(buf, res)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func mustReadNBytes(buf *bytes.Buffer, n int) []byte {
|
||||
res, err := readNBytes(buf, n)
|
||||
panicIfError(err)
|
||||
return res
|
||||
}
|
Loading…
Reference in a new issue