tunnel: buffer WriteFrames into single TLS write
Assemble numBlocks + frame sizes + frame data into one buffer before writing. Reduces TLS records and syscalls from 3 per frame to 1. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fc07ac507d
commit
14ec4a02dd
1 changed files with 23 additions and 12 deletions
|
|
@ -85,20 +85,31 @@ func (t *Tunnel) ReadFrames() ([][]byte, error) {
|
|||
|
||||
// WriteFrames sends a batch of Ethernet frames to the server.
|
||||
// Safe for concurrent use from multiple goroutines.
|
||||
// Assembles the entire message into one buffer for a single TLS write.
|
||||
func (t *Tunnel) WriteFrames(frames [][]byte) error {
|
||||
t.writeMu.Lock()
|
||||
defer t.writeMu.Unlock()
|
||||
|
||||
if err := binary.Write(t.sess.Conn, binary.BigEndian, uint32(len(frames))); err != nil {
|
||||
return fmt.Errorf("write num blocks: %w", err)
|
||||
// Calculate total size: 4 (numBlocks) + per frame: 4 (size) + len(data)
|
||||
total := 4
|
||||
for _, f := range frames {
|
||||
total += 4 + len(f)
|
||||
}
|
||||
for _, frame := range frames {
|
||||
if err := binary.Write(t.sess.Conn, binary.BigEndian, uint32(len(frame))); err != nil {
|
||||
return fmt.Errorf("write block size: %w", err)
|
||||
}
|
||||
if _, err := t.sess.Conn.Write(frame); err != nil {
|
||||
return fmt.Errorf("write block data: %w", err)
|
||||
}
|
||||
|
||||
buf := make([]byte, total)
|
||||
off := 0
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(len(frames)))
|
||||
off += 4
|
||||
for _, f := range frames {
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(len(f)))
|
||||
off += 4
|
||||
copy(buf[off:], f)
|
||||
off += len(f)
|
||||
}
|
||||
|
||||
t.writeMu.Lock()
|
||||
_, err := t.sess.Conn.Write(buf)
|
||||
t.writeMu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("write frames: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue