mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-10-18 05:33:32 -04:00
90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
|
package oscar
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"log"
|
||
|
"net"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
type Handler struct {
|
||
|
services map[uint16]Service
|
||
|
}
|
||
|
|
||
|
func NewHandler() *Handler {
|
||
|
return &Handler{
|
||
|
services: make(map[uint16]Service),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (h *Handler) RegisterService(family uint16, service Service) {
|
||
|
h.services[family] = service
|
||
|
}
|
||
|
|
||
|
func (h *Handler) Handle(conn net.Conn) {
|
||
|
session := NewSession(conn)
|
||
|
buf := make([]byte, 1024)
|
||
|
for {
|
||
|
if !session.GreetedClient {
|
||
|
// send a hello
|
||
|
hello := NewFLAP(1)
|
||
|
hello.Data.Write([]byte{0, 0, 0, 1})
|
||
|
err := session.Send(hello)
|
||
|
panicIfError(err)
|
||
|
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
|
||
|
}
|
||
|
|
||
|
// 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)
|
||
|
|
||
|
if flap.Header.Channel == 1 {
|
||
|
|
||
|
} else if flap.Header.Channel == 2 {
|
||
|
snac := &SNAC{}
|
||
|
err := snac.UnmarshalBinary(flap.Data.Bytes())
|
||
|
panicIfError(err)
|
||
|
|
||
|
fmt.Printf("%+v\n", snac)
|
||
|
if tlvs, err := UnmarshalTLVs(snac.Data.Bytes()); err == nil {
|
||
|
for _, tlv := range tlvs {
|
||
|
fmt.Printf("%+v\n", tlv)
|
||
|
}
|
||
|
} else {
|
||
|
fmt.Printf("%s\n\n", prettyBytes(snac.Data.Bytes()))
|
||
|
}
|
||
|
|
||
|
if service, ok := h.services[snac.Header.Family]; ok {
|
||
|
err = service.HandleSNAC(session, snac)
|
||
|
panicIfError(err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|