mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-22 12:58:37 +00:00
start to handle L2 vs L3 properly
Change-Id: I0efc9320aff419dc4b3e97c623c9af7f9d5dd48a Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
c860129eb0
commit
e617cf5af8
@ -263,7 +263,7 @@ func (n *network) acceptTCP(r *tcp.ForwarderRequest) {
|
|||||||
if reqDetails.LocalPort == 123 {
|
if reqDetails.LocalPort == 123 {
|
||||||
r.Complete(false)
|
r.Complete(false)
|
||||||
tc := gonet.NewTCPConn(&wq, ep)
|
tc := gonet.NewTCPConn(&wq, ep)
|
||||||
io.WriteString(tc, "Hello Andrew from Go\nGoodbye.\n")
|
io.WriteString(tc, "Hello from Go\nGoodbye.\n")
|
||||||
tc.Close()
|
tc.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -300,8 +300,16 @@ func (ep EthernetPacket) SrcMAC() MAC {
|
|||||||
return MAC(ep.le.SrcMAC)
|
return MAC(ep.le.SrcMAC)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ep EthernetPacket) DstMAC() MAC {
|
||||||
|
return MAC(ep.le.DstMAC)
|
||||||
|
}
|
||||||
|
|
||||||
type MAC [6]byte
|
type MAC [6]byte
|
||||||
|
|
||||||
|
func (m MAC) IsBroadcast() bool {
|
||||||
|
return m == MAC{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||||
|
}
|
||||||
|
|
||||||
func macOf(hwa net.HardwareAddr) (_ MAC, ok bool) {
|
func macOf(hwa net.HardwareAddr) (_ MAC, ok bool) {
|
||||||
if len(hwa) != 6 {
|
if len(hwa) != 6 {
|
||||||
return MAC{}, false
|
return MAC{}, false
|
||||||
@ -461,20 +469,39 @@ func (s *Server) serveConn(uc net.Conn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeEth writes a raw Ethernet frame to all (0, 1, or multiple) connected
|
||||||
|
// clients on the network.
|
||||||
|
//
|
||||||
|
// This only delivers to client devices and not the virtual router/gateway
|
||||||
|
// device.
|
||||||
func (n *network) writeEth(res []byte) {
|
func (n *network) writeEth(res []byte) {
|
||||||
if len(res) < 6 {
|
if len(res) < 12 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dstMAC := MAC(res[0:6])
|
dstMAC := MAC(res[0:6])
|
||||||
|
srcMAC := MAC(res[6:12])
|
||||||
|
if dstMAC.IsBroadcast() {
|
||||||
|
n.writeFunc.Range(func(mac MAC, writeFunc func([]byte)) bool {
|
||||||
|
writeFunc(res)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if srcMAC == dstMAC {
|
||||||
|
log.Printf("dropping write of packet from %v to itself", srcMAC)
|
||||||
|
return
|
||||||
|
}
|
||||||
if writeFunc, ok := n.writeFunc.Load(dstMAC); ok {
|
if writeFunc, ok := n.writeFunc.Load(dstMAC); ok {
|
||||||
writeFunc(res)
|
writeFunc(res)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
||||||
packet := ep.gp
|
packet := ep.gp
|
||||||
s := n.s
|
dstMAC := ep.DstMAC()
|
||||||
writePkt := n.writeEth
|
isBroadcast := dstMAC.IsBroadcast()
|
||||||
|
forRouter := dstMAC == n.mac || isBroadcast
|
||||||
|
|
||||||
switch ep.le.EthernetType {
|
switch ep.le.EthernetType {
|
||||||
default:
|
default:
|
||||||
@ -485,7 +512,7 @@ func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("createARPResponse: %v", err)
|
log.Printf("createARPResponse: %v", err)
|
||||||
} else {
|
} else {
|
||||||
writePkt(res)
|
n.writeEth(res)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case layers.EthernetTypeIPv6:
|
case layers.EthernetTypeIPv6:
|
||||||
@ -496,8 +523,26 @@ func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
|||||||
// Below
|
// Below
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send ethernet broadcasts and unicast ethernet frames to peers
|
||||||
|
// on the same network. This is all LAN traffic that isn't meant
|
||||||
|
// for the router/gw itself:
|
||||||
|
n.writeEth(ep.gp.Data())
|
||||||
|
|
||||||
|
if forRouter {
|
||||||
|
n.HandleEthernetIPv4PacketForRouter(ep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleEthernetIPv4PacketForRouter handles an IPv4 packet that is
|
||||||
|
// directed to the router/gateway itself. The packet may be to the
|
||||||
|
// broadcast MAC address, or to the router's MAC address. The target
|
||||||
|
// IP may be the router's IP, or an internet (routed) IP.
|
||||||
|
func (n *network) HandleEthernetIPv4PacketForRouter(ep EthernetPacket) {
|
||||||
|
packet := ep.gp
|
||||||
|
writePkt := n.writeEth
|
||||||
|
|
||||||
if isDHCPRequest(packet) {
|
if isDHCPRequest(packet) {
|
||||||
res, err := s.createDHCPResponse(packet)
|
res, err := n.s.createDHCPResponse(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("createDHCPResponse: %v", err)
|
log.Printf("createDHCPResponse: %v", err)
|
||||||
return
|
return
|
||||||
@ -512,7 +557,7 @@ func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isDNSRequest(packet) {
|
if isDNSRequest(packet) {
|
||||||
res, err := s.createDNSResponse(packet)
|
res, err := n.s.createDNSResponse(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("createDNSResponse: %v", err)
|
log.Printf("createDNSResponse: %v", err)
|
||||||
return
|
return
|
||||||
@ -523,7 +568,7 @@ func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
|||||||
|
|
||||||
if isSTUNRequest(packet) {
|
if isSTUNRequest(packet) {
|
||||||
log.Printf("STUN request in")
|
log.Printf("STUN request in")
|
||||||
res, err := s.createSTUNResponse(packet)
|
res, err := n.s.createSTUNResponse(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("createSTUNResponse: %v", err)
|
log.Printf("createSTUNResponse: %v", err)
|
||||||
return
|
return
|
||||||
@ -541,12 +586,6 @@ func (n *network) HandleEthernetPacket(ep EthernetPacket) {
|
|||||||
Payload: buffer.MakeWithData(pktCopy),
|
Payload: buffer.MakeWithData(pktCopy),
|
||||||
})
|
})
|
||||||
n.linkEP.InjectInbound(header.IPv4ProtocolNumber, packetBuf)
|
n.linkEP.InjectInbound(header.IPv4ProtocolNumber, packetBuf)
|
||||||
|
|
||||||
// var list stack.PacketBufferList
|
|
||||||
// list.PushBack(packetBuf)
|
|
||||||
// n, err := s.linkEP.WritePackets(list)
|
|
||||||
// log.Printf("Injected: %v, %v", n, err)
|
|
||||||
|
|
||||||
packetBuf.DecRef()
|
packetBuf.DecRef()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user