aim-oscar-server/oscar/server.go

93 lines
1.9 KiB
Go
Raw Permalink Normal View History

2021-12-16 19:45:32 -05:00
package oscar
import (
"aim-oscar/util"
2022-01-23 13:22:05 -05:00
"bytes"
"context"
"encoding/binary"
2022-01-22 20:57:27 -05:00
"fmt"
2021-12-16 19:45:32 -05:00
"io"
"log"
"net"
"strings"
2022-02-11 13:28:20 -05:00
"time"
2021-12-16 19:45:32 -05:00
)
type HandlerFunc func(context.Context, *FLAP) context.Context
2021-12-18 17:10:00 -05:00
type HandleCloseFn func(context.Context, *Session)
2021-12-18 17:10:00 -05:00
type Handler struct {
handle HandlerFunc
handleClose HandleCloseFn
}
2021-12-16 19:45:32 -05:00
2021-12-18 17:10:00 -05:00
func NewHandler(fn HandlerFunc, handleClose HandleCloseFn) *Handler {
2021-12-16 19:45:32 -05:00
return &Handler{
2021-12-18 17:10:00 -05:00
handle: fn,
handleClose: handleClose,
2021-12-16 19:45:32 -05:00
}
}
func (h *Handler) Handle(conn net.Conn) {
ctx := NewContextWithSession(context.Background(), conn)
session, _ := SessionFromContext(ctx)
2022-01-23 13:22:05 -05:00
var buf bytes.Buffer
2021-12-16 19:45:32 -05:00
for {
if !session.GreetedClient {
// send a hello
hello := NewFLAP(1)
hello.Data.Write([]byte{0, 0, 0, 1})
2022-01-22 20:57:27 -05:00
session.Send(hello)
2021-12-16 19:45:32 -05:00
session.GreetedClient = true
}
2022-02-11 13:28:20 -05:00
// Never timeout
conn.SetReadDeadline(time.Time{})
2022-01-23 13:22:05 -05:00
incoming := make([]byte, 512)
n, err := conn.Read(incoming)
2021-12-16 19:45:32 -05:00
if err != nil && err != io.EOF {
if strings.Contains(err.Error(), "use of closed network connection") {
session.Disconnect()
2021-12-18 17:10:00 -05:00
h.handleClose(ctx, session)
return
}
log.Println("OSCAR Read Error: ", err.Error())
2021-12-16 19:45:32 -05:00
return
}
if n == 0 {
return
}
2022-01-23 13:22:05 -05:00
buf.Write(incoming[:n])
2021-12-16 19:45:32 -05:00
// Try to parse all of the FLAPs in the buffer if we have enough bytes to
// fill a FLAP header
2022-01-23 13:22:05 -05:00
for buf.Len() >= 6 && buf.Bytes()[0] == 0x2a {
bufBytes := buf.Bytes()
dataLength := binary.BigEndian.Uint16(bufBytes[4:6])
2021-12-16 19:45:32 -05:00
flapLength := int(dataLength) + 6
2022-01-23 13:22:05 -05:00
if len(bufBytes) < flapLength {
log.Printf("not enough data, expected %d bytes but have %d bytes\n", flapLength, len(bufBytes))
fmt.Printf("%s\n", util.PrettyBytes(bufBytes))
2021-12-16 19:45:32 -05:00
break
}
flap := &FLAP{}
2022-01-23 13:22:05 -05:00
flapBuf := make([]byte, flapLength)
buf.Read(flapBuf)
if err := flap.UnmarshalBinary(flapBuf); err != nil {
2022-02-03 14:06:33 -05:00
log.Printf("could not unmarshal FLAP: %w", err)
// Toss out everything
buf.Reset()
break
2021-12-16 19:45:32 -05:00
}
2022-01-23 13:22:05 -05:00
ctx = h.handle(ctx, flap)
2021-12-16 19:45:32 -05:00
}
}
}