From 1d1ea6ea449058c285eef8d0f284302556d97a83 Mon Sep 17 00:00:00 2001 From: Nonoo Date: Fri, 23 Oct 2020 18:36:47 +0200 Subject: [PATCH] Rework login --- controlstream.go | 34 +++++++++++++++++++--------------- main.go | 22 +++++++++++++++------- pkt7.go | 12 +++++++----- streamcommon.go | 6 ------ 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/controlstream.go b/controlstream.go index 1865fbb..907e504 100644 --- a/controlstream.go +++ b/controlstream.go @@ -22,8 +22,9 @@ type controlStream struct { authInnerSendSeq uint16 authID [6]byte - serialAndAudioStreamOpened bool - deinitializing bool + serialAndAudioStreamOpenRequested bool + serialAndAudioStreamOpened bool + deinitializing bool secondAuthTimer *time.Timer requestSerialAndAudioTimeout *time.Timer @@ -154,9 +155,7 @@ func (s *controlStream) sendRequestSerialAndAudio() error { s.authSendSeq++ s.authInnerSendSeq++ - s.requestSerialAndAudioTimeout = time.AfterFunc(3*time.Second, func() { - reportError(errors.New("serial and audio request timeout")) - }) + s.serialAndAudioStreamOpenRequested = true return nil } @@ -185,6 +184,7 @@ func (s *controlStream) handleRead(r []byte) error { if r[21] == 0x05 && !s.serialAndAudioStreamOpened { // Answer for our second auth? s.secondAuthTimer.Stop() + if err := s.sendRequestSerialAndAudio(); err != nil { reportError(err) } @@ -226,6 +226,14 @@ func (s *controlStream) handleRead(r []byte) error { // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x03, 0x03, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + if !bytes.Equal(r[26:32], s.authID[:]) { + return errors.New("got serial and audio request success, but not for our auth id") + } + if !s.serialAndAudioStreamOpenRequested { + return errors.New("got serial and audio request success, but not requested yet") + } + devName := s.parseNullTerminatedString(r[64:]) log.Print("serial and audio request success, device name: ", devName) if s.requestSerialAndAudioTimeout != nil { @@ -254,8 +262,6 @@ func (s *controlStream) loop() { pkt0SendTicker := time.NewTicker(100 * time.Millisecond) reauthTicker := time.NewTicker(60 * time.Second) statusLogTicker := time.NewTicker(3 * time.Second) - logoutTimer := time.NewTimer(3300 * time.Millisecond) - logoutTimer.Stop() for { select { @@ -284,11 +290,6 @@ func (s *controlStream) loop() { log.Print("running for ", time.Since(startTime), " roundtrip latency ", s.common.pkt7.latency) } case <-s.deinitNeededChan: - log.Print("sending logout auth") - _ = s.sendPktAuth(false) - - logoutTimer.Reset(3300 * time.Millisecond) - case <-logoutTimer.C: s.deinitFinishedChan <- true return } @@ -354,6 +355,10 @@ func (s *controlStream) start() error { s.common.pkt7.startPeriodicSend(&s.common, 5, false) + s.requestSerialAndAudioTimeout = time.AfterFunc(5*time.Second, func() { + reportError(errors.New("login/serial/audio request timeout")) + }) + s.deinitNeededChan = make(chan bool) s.deinitFinishedChan = make(chan bool) go s.loop() @@ -373,9 +378,6 @@ func (s *controlStream) init() error { } func (s *controlStream) deinit() { - s.audio.deinit() - s.serial.deinit() - s.deinitializing = true s.serialAndAudioStreamOpened = false @@ -388,4 +390,6 @@ func (s *controlStream) deinit() { s.requestSerialAndAudioTimeout = nil } s.common.deinit() + s.audio.deinit() + s.serial.deinit() } diff --git a/main.go b/main.go index 9e453ce..3bc701d 100644 --- a/main.go +++ b/main.go @@ -24,22 +24,35 @@ func runControlStream(osSignal chan os.Signal) (shouldExit bool, exitCode int) { } c := controlStream{} - defer c.deinit() if err := c.init(); err != nil { log.Error(err) + c.deinit() return true, 1 } if err := c.start(); err != nil { log.Error(err) + c.deinit() return } select { case <-gotErrChan: + c.deinit() + + t := time.NewTicker(time.Second) + for sec := 180; sec > 0; sec-- { + log.Print("waiting ", sec, " seconds...") + select { + case <-t.C: + case <-osSignal: + return true, 0 + } + } return case <-osSignal: log.Print("sigterm received") + c.deinit() return true, 0 } } @@ -51,7 +64,7 @@ func reportError(err error) { // Non-blocking notify. select { - case gotErrChan <- true: + case gotErrChan <- false: default: } } @@ -70,11 +83,6 @@ func main() { shouldExit, exitCode = runControlStream(osSignal) if !shouldExit { log.Print("restarting control stream...") - select { - case <-time.NewTimer(3 * time.Second).C: - case <-osSignal: - shouldExit = true - } } } diff --git a/pkt7.go b/pkt7.go index 01eb994..3f1b1d4 100644 --- a/pkt7.go +++ b/pkt7.go @@ -14,7 +14,7 @@ const pkt7TimeoutDuration = 3 * time.Second type pkt7Type struct { sendSeq uint16 - randIDBytes [2]byte + innerSendSeq uint16 lastConfirmedSeq uint16 sendTicker *time.Ticker @@ -74,14 +74,15 @@ func (p *pkt7Type) sendDo(s *streamCommon, replyID []byte, seq uint16) error { var replyFlag byte if replyID == nil { replyID = make([]byte, 4) - var randID [2]byte + var randID [1]byte if _, err := rand.Read(randID[:]); err != nil { return err } replyID[0] = randID[0] - replyID[1] = randID[1] - replyID[2] = p.randIDBytes[0] - replyID[3] = p.randIDBytes[1] + replyID[1] = byte(p.innerSendSeq) + replyID[2] = byte(p.innerSendSeq >> 8) + replyID[3] = 0x05 + p.innerSendSeq++ } else { replyFlag = 0x01 } @@ -142,6 +143,7 @@ func (p *pkt7Type) loop(s *streamCommon) { func (p *pkt7Type) startPeriodicSend(s *streamCommon, firstSeqNo uint16, checkPingTimeout bool) { p.sendSeq = firstSeqNo + p.innerSendSeq = 0x8304 p.lastConfirmedSeq = p.sendSeq - 1 p.sendTicker = time.NewTicker(100 * time.Millisecond) diff --git a/streamcommon.go b/streamcommon.go index c0168b0..6ea7ef5 100644 --- a/streamcommon.go +++ b/streamcommon.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "crypto/rand" "encoding/binary" "errors" "fmt" @@ -163,11 +162,6 @@ func (s *streamCommon) init(name string, portNumber int) error { laddr := s.conn.LocalAddr().(*net.UDPAddr) s.localSID = binary.BigEndian.Uint32(laddr.IP[len(laddr.IP)-4:])<<16 | uint32(laddr.Port&0xffff) - _, err = rand.Read(s.pkt7.randIDBytes[:]) - if err != nil { - return err - } - s.readChan = make(chan []byte) s.readerCloseNeededChan = make(chan bool) s.readerCloseFinishedChan = make(chan bool)