The inject goroutine reads in packets that netstack generated, and delivers them to the correct path.
()
| 1045 | // The inject goroutine reads in packets that netstack generated, and delivers |
| 1046 | // them to the correct path. |
| 1047 | func (ns *Impl) inject() { |
| 1048 | inboundBuffs, inboundBuffsSizes := ns.getInjectInboundBuffsSizes() |
| 1049 | for { |
| 1050 | pkt := ns.linkEP.ReadContext(ns.ctx) |
| 1051 | if pkt == nil { |
| 1052 | if ns.ctx.Err() != nil { |
| 1053 | // Return without logging. |
| 1054 | return |
| 1055 | } |
| 1056 | ns.logf("[v2] ReadContext-for-write = ok=false") |
| 1057 | continue |
| 1058 | } |
| 1059 | |
| 1060 | if debugPackets { |
| 1061 | ns.logf("[v2] packet Write out: % x", stack.PayloadSince(pkt.NetworkHeader()).AsSlice()) |
| 1062 | } |
| 1063 | |
| 1064 | // In the normal case, netstack synthesizes the bytes for |
| 1065 | // traffic which should transit back into WG and go to peers. |
| 1066 | // However, some uses of netstack (presently, magic DNS) |
| 1067 | // send traffic destined for the local device, hence must |
| 1068 | // be injected 'inbound'. |
| 1069 | sendToHost := ns.shouldSendToHost(pkt) |
| 1070 | |
| 1071 | // pkt has a non-zero refcount, so injection methods takes |
| 1072 | // ownership of one count and will decrement on completion. |
| 1073 | if sendToHost { |
| 1074 | if err := ns.tundev.InjectInboundPacketBuffer(pkt, inboundBuffs, inboundBuffsSizes); err != nil { |
| 1075 | ns.logf("netstack inject inbound: %v", err) |
| 1076 | return |
| 1077 | } |
| 1078 | } else { |
| 1079 | // Self-addressed packet: deliver back into gVisor directly |
| 1080 | // via the link endpoint's dispatcher, but only if the packet is not |
| 1081 | // earmarked for the host. Neither the inbound path (fakeTUN Write is a |
| 1082 | // no-op) nor the outbound path (WireGuard has no peer for our own IP) |
| 1083 | // can handle these. |
| 1084 | if ns.isSelfDst(pkt) { |
| 1085 | ns.linkEP.DeliverLoopback(pkt) |
| 1086 | continue |
| 1087 | } |
| 1088 | |
| 1089 | if err := ns.tundev.InjectOutboundPacketBuffer(pkt); err != nil { |
| 1090 | ns.logf("netstack inject outbound: %v", err) |
| 1091 | return |
| 1092 | } |
| 1093 | } |
| 1094 | } |
| 1095 | } |
| 1096 | |
| 1097 | // shouldSendToHost determines if the provided packet should be sent to the |
| 1098 | // host (i.e the current machine running Tailscale), in which case it will |
no test coverage detected