ipn/message: fix some message encoding problems.
Reset() was not including a Version field, so was getting rejected;
the Logout operation no longer happened when the client got disconnected.
Don't crash if we can't decode 0-byte messages, which I suspect might
sometimes come through on EOF.
@@ -75,15 +75,23 @@ func (bs *BackendServer) send(n Notify) {
// calls GotCommand with it.
func (bs *BackendServer) GotCommandMsg(b []byte) error {
cmd := &Command{}
+ if len(b) == 0 {
+ return nil
+ }
if err := json.Unmarshal(b, cmd); err != nil {
return err
}
return bs.GotCommand(cmd)
}
+func (bs *BackendServer) GotFakeCommand(cmd *Command) error {
+ cmd.Version = version.LONG
+ return bs.GotCommand(cmd)
+}
+
func (bs *BackendServer) GotCommand(cmd *Command) error {
if cmd.Version != version.LONG {
- vs := fmt.Sprintf("Version mismatch! frontend=%#v backend=%#v",
+ vs := fmt.Sprintf("GotCommand: Version mismatch! frontend=%#v backend=%#v",
cmd.Version, version.LONG)
bs.logf("%s", vs)
// ignore the command, but send a message back to the
@@ -130,7 +138,7 @@ func (bs *BackendServer) GotCommand(cmd *Command) error {
func (bs *BackendServer) Reset() error {
// Tell the backend we got a Logout command, which will cause it
// to forget all its authentication information.
- return bs.GotCommand(&Command{Logout: &NoArgs{}})
+ return bs.GotFakeCommand(&Command{Logout: &NoArgs{}})
}
type BackendClient struct {
@@ -147,12 +155,16 @@ func NewBackendClient(logf logger.Logf, sendCommandMsg func(jsonb []byte)) *Back
}
func (bc *BackendClient) GotNotifyMsg(b []byte) {
+ if len(b) == 0 {
+ // not interesting
+ return
+ }
n := Notify{}
if err := json.Unmarshal(b, &n); err != nil {
- log.Fatalf("BackendClient.Notify: cannot decode message")
+ log.Fatalf("BackendClient.Notify: cannot decode message (length=%d)\n%#v", len(b), string(b))
}
if n.Version != version.LONG {
- vs := fmt.Sprintf("Version mismatch! frontend=%#v backend=%#v",
+ vs := fmt.Sprintf("GotNotify: Version mismatch! frontend=%#v backend=%#v",
version.LONG, n.Version)
bc.logf("%s", vs)
// delete anything in the notification except the version,
@@ -232,10 +244,13 @@ func ReadMsg(r io.Reader) ([]byte, error) {
return nil, fmt.Errorf("ipn.Read: message too large: %v bytes", n)
}
b := make([]byte, n)
- _, err = io.ReadFull(r, b)
+ nn, err := io.ReadFull(r, b)
if err != nil {
return nil, err
}
+ if nn != int(n) {
+ return nil, fmt.Errorf("ipn.Read: expected %v bytes, got %v", n, nn)
+ }
return b, nil
}
