ping: Add logs

This commit is contained in:
世界 2025-08-24 12:39:56 +08:00
parent 7f41766568
commit d53158b8d7
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 24 additions and 8 deletions

View file

@ -30,11 +30,11 @@ func ConnectDestination(ctx context.Context, logger logger.ContextLogger, contro
) )
switch runtime.GOOS { switch runtime.GOOS {
case "darwin", "ios", "windows": case "darwin", "ios", "windows":
conn, err = Connect(false, controlFunc, address) conn, err = Connect(ctx, logger, false, controlFunc, address)
default: default:
conn, err = Connect(true, controlFunc, address) conn, err = Connect(ctx, logger, true, controlFunc, address)
if errors.Is(err, os.ErrPermission) { if errors.Is(err, os.ErrPermission) {
conn, err = Connect(false, controlFunc, address) conn, err = Connect(ctx, logger, false, controlFunc, address)
} }
} }
if err != nil { if err != nil {

View file

@ -1,6 +1,7 @@
package ping package ping
import ( import (
"context"
"net" "net"
"net/netip" "net/netip"
"reflect" "reflect"
@ -14,6 +15,7 @@ import (
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
"golang.org/x/net/ipv4" "golang.org/x/net/ipv4"
@ -21,18 +23,22 @@ import (
) )
type Conn struct { type Conn struct {
ctx context.Context
logger logger.ContextLogger
privileged bool privileged bool
conn net.Conn conn net.Conn
destination netip.Addr destination netip.Addr
source atomic.TypedValue[netip.Addr] source atomic.TypedValue[netip.Addr]
} }
func Connect(privileged bool, controlFunc control.Func, destination netip.Addr) (*Conn, error) { func Connect(ctx context.Context, logger logger.ContextLogger, privileged bool, controlFunc control.Func, destination netip.Addr) (*Conn, error) {
conn, err := connect(privileged, controlFunc, destination) conn, err := connect(privileged, controlFunc, destination)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Conn{ return &Conn{
ctx: ctx,
logger: logger,
privileged: privileged, privileged: privileged,
conn: conn, conn: conn,
destination: destination, destination: destination,
@ -95,6 +101,7 @@ func (c *Conn) ReadIP(buffer *buf.Buffer) error {
TotalLength: uint16(buffer.Len()), TotalLength: uint16(buffer.Len()),
}) })
ipHdr.SetChecksum(^ipHdr.CalculateChecksum()) ipHdr.SetChecksum(^ipHdr.CalculateChecksum())
c.logger.TraceContext(c.ctx, "read icmpv4 echo reply from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
} else { } else {
oob := make([]byte, 1024) oob := make([]byte, 1024)
buffer.Advance(header.IPv6MinimumSize) buffer.Advance(header.IPv6MinimumSize)
@ -131,6 +138,7 @@ func (c *Conn) ReadIP(buffer *buf.Buffer) error {
SrcAddr: addr, SrcAddr: addr,
DstAddr: c.source.Load(), DstAddr: c.source.Load(),
}) })
c.logger.TraceContext(c.ctx, "read icmpv6 echo reply from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
} }
} else { } else {
_, err := buffer.ReadOnceFrom(c.conn) _, err := buffer.ReadOnceFrom(c.conn)
@ -144,6 +152,7 @@ func (c *Conn) ReadIP(buffer *buf.Buffer) error {
ipHdr.SetChecksum(^ipHdr.CalculateChecksum()) ipHdr.SetChecksum(^ipHdr.CalculateChecksum())
icmpHdr := header.ICMPv4(ipHdr.Payload()) icmpHdr := header.ICMPv4(ipHdr.Payload())
icmpHdr.SetChecksum(header.ICMPv4Checksum(icmpHdr[:header.ICMPv4MinimumSize], checksum.Checksum(icmpHdr.Payload(), 0))) icmpHdr.SetChecksum(header.ICMPv4Checksum(icmpHdr[:header.ICMPv4MinimumSize], checksum.Checksum(icmpHdr.Payload(), 0)))
c.logger.TraceContext(c.ctx, "read icmpv4 echo reply from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
} else { } else {
ipHdr := header.IPv6(buffer.Bytes()) ipHdr := header.IPv6(buffer.Bytes())
ipHdr.SetDestinationAddr(c.source.Load()) ipHdr.SetDestinationAddr(c.source.Load())
@ -153,6 +162,7 @@ func (c *Conn) ReadIP(buffer *buf.Buffer) error {
Src: ipHdr.SourceAddressSlice(), Src: ipHdr.SourceAddressSlice(),
Dst: ipHdr.DestinationAddressSlice(), Dst: ipHdr.DestinationAddressSlice(),
})) }))
c.logger.TraceContext(c.ctx, "read icmpv6 echo reply from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
} }
} }
return nil return nil
@ -169,9 +179,11 @@ func (c *Conn) ReadICMP(buffer *buf.Buffer) error {
if !c.destination.Is6() { if !c.destination.Is6() {
ipHdr := header.IPv4(buffer.Bytes()) ipHdr := header.IPv4(buffer.Bytes())
buffer.Advance(int(ipHdr.HeaderLength())) buffer.Advance(int(ipHdr.HeaderLength()))
c.logger.TraceContext(c.ctx, "read icmpv4 echo reply from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
} else { } else {
ipHdr := header.IPv6(buffer.Bytes()) ipHdr := header.IPv6(buffer.Bytes())
buffer.Advance(buffer.Len() - int(ipHdr.PayloadLength())) buffer.Advance(buffer.Len() - int(ipHdr.PayloadLength()))
c.logger.TraceContext(c.ctx, "read icmpv6 echo reply from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
} }
return nil return nil
} }
@ -181,10 +193,12 @@ func (c *Conn) WriteIP(buffer *buf.Buffer) error {
if !c.destination.Is6() { if !c.destination.Is6() {
ipHdr := header.IPv4(buffer.Bytes()) ipHdr := header.IPv4(buffer.Bytes())
c.source.Store(M.AddrFromIP(ipHdr.SourceAddressSlice())) c.source.Store(M.AddrFromIP(ipHdr.SourceAddressSlice()))
c.logger.TraceContext(c.ctx, "write icmpv4 echo request from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
return common.Error(c.conn.Write(ipHdr.Payload())) return common.Error(c.conn.Write(ipHdr.Payload()))
} else { } else {
ipHdr := header.IPv6(buffer.Bytes()) ipHdr := header.IPv6(buffer.Bytes())
c.source.Store(M.AddrFromIP(ipHdr.SourceAddressSlice())) c.source.Store(M.AddrFromIP(ipHdr.SourceAddressSlice()))
c.logger.TraceContext(c.ctx, "write icmpv6 echo request from ", ipHdr.SourceAddr(), " to ", ipHdr.DestinationAddr())
return common.Error(c.conn.Write(ipHdr.Payload())) return common.Error(c.conn.Write(ipHdr.Payload()))
} }
} }

View file

@ -1,6 +1,7 @@
package ping_test package ping_test
import ( import (
"context"
"net/netip" "net/netip"
"os" "os"
"runtime" "runtime"
@ -11,6 +12,7 @@ import (
"github.com/sagernet/sing-tun/internal/gtcpip/header" "github.com/sagernet/sing-tun/internal/gtcpip/header"
"github.com/sagernet/sing-tun/ping" "github.com/sagernet/sing-tun/ping"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/logger"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -71,7 +73,7 @@ func TestPing(t *testing.T) {
} }
func testPingIPv4ReadIP(t *testing.T, privileged bool, addr string) { func testPingIPv4ReadIP(t *testing.T, privileged bool, addr string) {
conn, err := ping.Connect(privileged, nil, netip.MustParseAddr(addr)) conn, err := ping.Connect(context.Background(), logger.NOP(), privileged, nil, netip.MustParseAddr(addr))
if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" { if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" {
t.SkipNow() t.SkipNow()
} }
@ -103,7 +105,7 @@ func testPingIPv4ReadIP(t *testing.T, privileged bool, addr string) {
} }
func testPingIPv4ReadICMP(t *testing.T, privileged bool, addr string) { func testPingIPv4ReadICMP(t *testing.T, privileged bool, addr string) {
conn, err := ping.Connect(privileged, nil, netip.MustParseAddr(addr)) conn, err := ping.Connect(context.Background(), logger.NOP(), privileged, nil, netip.MustParseAddr(addr))
if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" { if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" {
t.SkipNow() t.SkipNow()
} }
@ -134,7 +136,7 @@ func testPingIPv4ReadICMP(t *testing.T, privileged bool, addr string) {
} }
func testPingIPv6ReadIP(t *testing.T, privileged bool, addr string) { func testPingIPv6ReadIP(t *testing.T, privileged bool, addr string) {
conn, err := ping.Connect(privileged, nil, netip.MustParseAddr(addr)) conn, err := ping.Connect(context.Background(), logger.NOP(), privileged, nil, netip.MustParseAddr(addr))
if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" { if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" {
t.SkipNow() t.SkipNow()
} }
@ -165,7 +167,7 @@ func testPingIPv6ReadIP(t *testing.T, privileged bool, addr string) {
} }
func testPingIPv6ReadICMP(t *testing.T, privileged bool, addr string) { func testPingIPv6ReadICMP(t *testing.T, privileged bool, addr string) {
conn, err := ping.Connect(privileged, nil, netip.MustParseAddr(addr)) conn, err := ping.Connect(context.Background(), logger.NOP(), privileged, nil, netip.MustParseAddr(addr))
if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" { if runtime.GOOS == "linux" && err != nil && err.Error() == "socket(): permission denied" {
t.SkipNow() t.SkipNow()
} }