123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package tunnel
- import (
- "errors"
- "net"
- "net/netip"
- "time"
- N "github.com/metacubex/mihomo/common/net"
- C "github.com/metacubex/mihomo/constant"
- "github.com/metacubex/mihomo/log"
- )
- func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error {
- addr := metadata.UDPAddr()
- if addr == nil {
- return errors.New("udp addr invalid")
- }
- if _, err := pc.WriteTo(packet.Data(), addr); err != nil {
- return err
- }
- // reset timeout
- _ = pc.SetReadDeadline(time.Now().Add(udpTimeout))
- return nil
- }
- func handleUDPToLocal(writeBack C.WriteBack, pc N.EnhancePacketConn, key string, oAddrPort netip.AddrPort, fAddr netip.Addr) {
- defer func() {
- _ = pc.Close()
- closeAllLocalCoon(key)
- natTable.Delete(key)
- }()
- for {
- _ = pc.SetReadDeadline(time.Now().Add(udpTimeout))
- data, put, from, err := pc.WaitReadFrom()
- if err != nil {
- return
- }
- fromUDPAddr, isUDPAddr := from.(*net.UDPAddr)
- if !isUDPAddr {
- fromUDPAddr = net.UDPAddrFromAddrPort(oAddrPort) // oAddrPort was Unmapped
- log.Warnln("server return a [%T](%s) which isn't a *net.UDPAddr, force replace to (%s), this may be caused by a wrongly implemented server", from, from, oAddrPort)
- } else if fromUDPAddr == nil {
- fromUDPAddr = net.UDPAddrFromAddrPort(oAddrPort) // oAddrPort was Unmapped
- log.Warnln("server return a nil *net.UDPAddr, force replace to (%s), this may be caused by a wrongly implemented server", oAddrPort)
- } else {
- _fromUDPAddr := *fromUDPAddr
- fromUDPAddr = &_fromUDPAddr // make a copy
- if fromAddr, ok := netip.AddrFromSlice(fromUDPAddr.IP); ok {
- fromAddr = fromAddr.Unmap()
- if fAddr.IsValid() && (oAddrPort.Addr() == fromAddr) { // oAddrPort was Unmapped
- fromAddr = fAddr.Unmap()
- }
- fromUDPAddr.IP = fromAddr.AsSlice()
- if fromAddr.Is4() {
- fromUDPAddr.Zone = "" // only ipv6 can have the zone
- }
- }
- }
- _, err = writeBack.WriteBack(data, fromUDPAddr)
- if put != nil {
- put()
- }
- if err != nil {
- return
- }
- }
- }
- func closeAllLocalCoon(lAddr string) {
- natTable.RangeForLocalConn(lAddr, func(key string, value *net.UDPConn) bool {
- conn := value
- conn.Close()
- log.Debugln("Closing TProxy local conn... lAddr=%s rAddr=%s", lAddr, key)
- return true
- })
- }
- func handleSocket(inbound, outbound net.Conn) {
- N.Relay(inbound, outbound)
- }
|