runner: silence some confusing errors when tests fail

When runner fails a test at the first connection, but the shim tries to
make a second connection before it is killed, the dispatcher doesn't
recognize the shim ID and we get a confusing message:

> Error dispatching connection: shim ID 55 not found

Fix this by remembering closed shim IDs and silently rejecting them.

Change-Id: Ic8afdd853da2ab3c9ef6d7102a5a0a7d52f905df
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/79808
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/shim_dispatcher.go b/ssl/test/runner/shim_dispatcher.go
index ad15d4f..4fd421f 100644
--- a/ssl/test/runner/shim_dispatcher.go
+++ b/ssl/test/runner/shim_dispatcher.go
@@ -26,11 +26,12 @@
 )
 
 type shimDispatcher struct {
-	lock       sync.Mutex
-	nextShimID uint64
-	listener   *net.TCPListener
-	shims      map[uint64]*shimListener
-	err        error
+	lock        sync.Mutex
+	nextShimID  uint64
+	listener    *net.TCPListener
+	shims       map[uint64]*shimListener
+	closedShims map[uint64]struct{}
+	err         error
 }
 
 func newShimDispatcher() (*shimDispatcher, error) {
@@ -42,7 +43,7 @@
 	if err != nil {
 		return nil, err
 	}
-	d := &shimDispatcher{listener: listener, shims: make(map[uint64]*shimListener)}
+	d := &shimDispatcher{listener: listener, shims: make(map[uint64]*shimListener), closedShims: make(map[uint64]struct{})}
 	go d.acceptLoop()
 	return d, nil
 }
@@ -63,6 +64,7 @@
 func (d *shimDispatcher) unregisterShim(l *shimListener) {
 	d.lock.Lock()
 	delete(d.shims, l.shimID)
+	d.closedShims[l.shimID] = struct{}{}
 	d.lock.Unlock()
 }
 
@@ -97,8 +99,17 @@
 	shimID := binary.LittleEndian.Uint64(buf[:])
 	d.lock.Lock()
 	shim, ok := d.shims[shimID]
+	_, closed := d.closedShims[shimID]
 	d.lock.Unlock()
 	if !ok {
+		// If the shim is known but already closed, just silently reject the
+		// connection. This may happen if runner fails the test at the shim's
+		// first connection, but the shim tries to make a second connection
+		// before it is killed.
+		if closed {
+			conn.Close()
+			return nil
+		}
 		return fmt.Errorf("shim ID %d not found", shimID)
 	}