Speak protocol 3.0 and fall back to 2.0 only when that is the reflector's maximum.
A reflector that has moved to 3.0 will not accept a station that always announces 2.0, and a 2.x reflector still needs one explicit plaintext session. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package station_test
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"io"
|
||||
@@ -133,10 +134,18 @@ type reflector struct {
|
||||
ln net.Listener
|
||||
udp *net.UDPConn
|
||||
tcp net.Conn
|
||||
tls *tls.Conn
|
||||
peer *net.UDPAddr
|
||||
port int
|
||||
}
|
||||
|
||||
func (r *reflector) conn() net.Conn {
|
||||
if r.tls != nil {
|
||||
return r.tls
|
||||
}
|
||||
return r.tcp
|
||||
}
|
||||
|
||||
func newReflector(t *testing.T) *reflector {
|
||||
t.Helper()
|
||||
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
@@ -166,16 +175,18 @@ func (r *reflector) accept(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r.tcp = conn
|
||||
r.tls = nil
|
||||
t.Cleanup(func() { conn.Close() })
|
||||
}
|
||||
|
||||
func (r *reflector) readFrame(t *testing.T) (uint16, []byte) {
|
||||
t.Helper()
|
||||
if err := r.tcp.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
conn := r.conn()
|
||||
if err := conn.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var hdr [4]byte
|
||||
if _, err := io.ReadFull(r.tcp, hdr[:]); err != nil {
|
||||
if _, err := io.ReadFull(conn, hdr[:]); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
n := binary.BigEndian.Uint32(hdr[:])
|
||||
@@ -183,7 +194,7 @@ func (r *reflector) readFrame(t *testing.T) (uint16, []byte) {
|
||||
t.Fatalf("frame length %d", n)
|
||||
}
|
||||
buf := make([]byte, n)
|
||||
if _, err := io.ReadFull(r.tcp, buf); err != nil {
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(buf) < 2 {
|
||||
@@ -199,14 +210,29 @@ func (r *reflector) writeFrame(t *testing.T, typ uint16, body []byte) {
|
||||
copy(payload[2:], body)
|
||||
var hdr [4]byte
|
||||
binary.BigEndian.PutUint32(hdr[:], uint32(len(payload)))
|
||||
if err := r.tcp.SetWriteDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
conn := r.conn()
|
||||
if err := conn.SetWriteDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := r.tcp.Write(append(hdr[:], payload...)); err != nil {
|
||||
if _, err := conn.Write(append(hdr[:], payload...)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *reflector) handshake(t *testing.T, cfg *tls.Config) error {
|
||||
t.Helper()
|
||||
r.tls = tls.Server(r.tcp, cfg)
|
||||
if err := r.tls.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
return err
|
||||
}
|
||||
err := r.tls.Handshake()
|
||||
_ = r.tls.SetDeadline(time.Time{})
|
||||
if err != nil {
|
||||
r.tls = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *reflector) readUDP(t *testing.T) (typ, id, seq uint16, body []byte) {
|
||||
t.Helper()
|
||||
if err := r.udp.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
@@ -228,6 +254,33 @@ func (r *reflector) readUDP(t *testing.T) (typ, id, seq uint16, body []byte) {
|
||||
return typ, id, seq, body
|
||||
}
|
||||
|
||||
func (r *reflector) readRawUDP(t *testing.T) []byte {
|
||||
t.Helper()
|
||||
if err := r.udp.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
buf := make([]byte, 2048)
|
||||
n, addr, err := r.udp.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r.peer = addr
|
||||
return append([]byte(nil), buf[:n]...)
|
||||
}
|
||||
|
||||
func (r *reflector) writeRawUDP(t *testing.T, pkt []byte) {
|
||||
t.Helper()
|
||||
if r.peer == nil {
|
||||
t.Fatal("no udp peer")
|
||||
}
|
||||
if err := r.udp.SetWriteDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := r.udp.WriteToUDP(pkt, r.peer); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *reflector) writeUDP(t *testing.T, typ, id, seq uint16, body []byte) {
|
||||
t.Helper()
|
||||
if r.peer == nil {
|
||||
@@ -294,8 +347,11 @@ func requireSoftwareIdentity(t *testing.T, body []byte) {
|
||||
if err := json.Unmarshal([]byte(raw), &got); err != nil {
|
||||
t.Fatalf("software identity %q: %v", raw, err)
|
||||
}
|
||||
if len(got) != 2 || got["sw"] != station.SoftwareName || got["swVer"] != station.SoftwareVersion {
|
||||
t.Fatalf("software identity = %#v, want sw %q and swVer %q only", got, station.SoftwareName, station.SoftwareVersion)
|
||||
if len(got) != 3 || got["sw"] != station.SoftwareName || got["swVer"] != station.SoftwareVersion || got["projVer"] != station.SoftwareVersion {
|
||||
t.Fatalf("software identity = %#v, want sw, swVer, and projVer %q", got, station.SoftwareName)
|
||||
}
|
||||
if _, ok := got["machineArch"]; ok {
|
||||
t.Fatal("protocol 2.0 node information includes machineArch")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user