Skip to content

Commit

Permalink
cleanup checks and re-use packet as out buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
wadey committed Nov 3, 2023
1 parent 7b874fc commit 1739d8c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 23 deletions.
23 changes: 11 additions & 12 deletions inside.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ func (f *Interface) rejectInside(packet []byte, out []byte, q int) {
}

out = iputil.CreateRejectPacket(packet, out)
if len(out) == 0 {
return
}

_, err := f.readers[q].Write(out)
if err != nil {
f.l.WithError(err).Error("Failed to write to tun")
Expand All @@ -101,27 +105,22 @@ func (f *Interface) rejectOutside(packet []byte, ci *ConnectionState, hostinfo *
return
}

// Use some out buffer space to build the packet before encryption
const aeadOverhead = 16
const maxOutLen = iputil.MaxRejectPacketSize + header.Len + aeadOverhead
outPacket := iputil.CreateRejectPacket(packet, out[maxOutLen:maxOutLen+iputil.MaxRejectPacketSize])
out = out[:maxOutLen]

if len(outPacket) == 0 {
out = iputil.CreateRejectPacket(packet, out)
if len(out) == 0 {
return
}

if len(outPacket) > iputil.MaxRejectPacketSize {
if f.l.GetLevel() >= logrus.DebugLevel {
if len(out) > iputil.MaxRejectPacketSize {
if f.l.GetLevel() >= logrus.InfoLevel {
f.l.
WithField("packet", packet).
WithField("outPacket", outPacket).
Debug("rejectOutside: packet too big, not sending")
WithField("outPacket", out).
Info("rejectOutside: packet too big, not sending")
}
return
}

f.sendNoMetrics(header.Message, 0, ci, hostinfo, nil, outPacket, nb, out, q)
f.sendNoMetrics(header.Message, 0, ci, hostinfo, nil, out, nb, packet, q)
}

func (f *Interface) Handshake(vpnIp iputil.VpnIp) {
Expand Down
18 changes: 8 additions & 10 deletions iputil/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ func CreateRejectPacket(packet []byte, out []byte) []byte {
func ipv4CreateRejectICMPPacket(packet []byte, out []byte) []byte {
ihl := int(packet[0]&0x0f) << 2

if ihl > 60 {
// invalid
return nil
}
if len(packet) < ihl {
// We need at least this many bytes for this to be a valid packet
return nil
Expand All @@ -46,8 +42,11 @@ func ipv4CreateRejectICMPPacket(packet []byte, out []byte) []byte {
}

outLen := ipv4.HeaderLen + 8 + packetLen
if outLen > cap(out) {
return nil
}

out = out[:(outLen)]
out = out[:outLen]

ipHdr := out[0:ipv4.HeaderLen]
ipHdr[0] = ipv4.Version<<4 | (ipv4.HeaderLen >> 2) // version, ihl
Expand Down Expand Up @@ -96,16 +95,15 @@ func ipv4CreateRejectTCPPacket(packet []byte, out []byte) []byte {
ihl := int(packet[0]&0x0f) << 2
outLen := ipv4.HeaderLen + tcpLen

if ihl > 60 {
// invalid
return nil
}
if len(packet) < ihl+tcpLen {
// We need at least this many bytes for this to be a valid packet
return nil
}
if outLen > cap(out) {
return nil
}

out = out[:(outLen)]
out = out[:outLen]

ipHdr := out[0:ipv4.HeaderLen]
ipHdr[0] = ipv4.Version<<4 | (ipv4.HeaderLen >> 2) // version, ihl
Expand Down
4 changes: 3 additions & 1 deletion outside.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,9 @@ func (f *Interface) decryptToTun(hostinfo *HostInfo, messageCounter uint64, out

dropReason := f.firewall.Drop(out, *fwPacket, true, hostinfo, f.pki.GetCAPool(), localCache)
if dropReason != nil {
f.rejectOutside(out, hostinfo.ConnectionState, hostinfo, nb, out, q)
// NOTE: We give `packet` as the `out` here since we already decrypted from it and we don't need it anymore
// This gives us a buffer to build the reject packet in
f.rejectOutside(out, hostinfo.ConnectionState, hostinfo, nb, packet, q)
if f.l.Level >= logrus.DebugLevel {
hostinfo.logger(f.l).WithField("fwPacket", fwPacket).
WithField("reason", dropReason).
Expand Down

0 comments on commit 1739d8c

Please sign in to comment.