mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
Direct/Freedom outbound: Block UDP responses that are come from ipsBlocked as well (#5952)
https://github.com/XTLS/Xray-core/pull/5947#issuecomment-4258980670 https://github.com/XTLS/Xray-core/pull/5952#issuecomment-4259324234 --------- Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
This commit is contained in:
@@ -290,7 +290,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
if destination.Network == net.Network_TCP {
|
if destination.Network == net.Network_TCP {
|
||||||
reader = buf.NewReader(conn)
|
reader = buf.NewReader(conn)
|
||||||
} else {
|
} else {
|
||||||
reader = NewPacketReader(conn, UDPOverride, destination)
|
reader = NewPacketReader(conn, UDPOverride, destination, blockedIPMatcher)
|
||||||
}
|
}
|
||||||
if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
|
if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
|
||||||
return errors.New("failed to process response").Base(err)
|
return errors.New("failed to process response").Base(err)
|
||||||
@@ -309,7 +309,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.Destination) buf.Reader {
|
func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.Destination, blockedIPMatcher geodata.IPMatcher) buf.Reader {
|
||||||
iConn := conn
|
iConn := conn
|
||||||
statConn, ok := iConn.(*stat.CounterConnection)
|
statConn, ok := iConn.(*stat.CounterConnection)
|
||||||
if ok {
|
if ok {
|
||||||
@@ -328,6 +328,7 @@ func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.De
|
|||||||
return &PacketReader{
|
return &PacketReader{
|
||||||
PacketConnWrapper: c,
|
PacketConnWrapper: c,
|
||||||
Counter: counter,
|
Counter: counter,
|
||||||
|
BlockedIPMatcher: blockedIPMatcher,
|
||||||
IsOverridden: isOverridden,
|
IsOverridden: isOverridden,
|
||||||
InitUnchangedAddr: DialDest.Address,
|
InitUnchangedAddr: DialDest.Address,
|
||||||
InitChangedAddr: net.DestinationFromAddr(conn.RemoteAddr()).Address,
|
InitChangedAddr: net.DestinationFromAddr(conn.RemoteAddr()).Address,
|
||||||
@@ -339,6 +340,7 @@ func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.De
|
|||||||
type PacketReader struct {
|
type PacketReader struct {
|
||||||
*internet.PacketConnWrapper
|
*internet.PacketConnWrapper
|
||||||
stats.Counter
|
stats.Counter
|
||||||
|
BlockedIPMatcher geodata.IPMatcher
|
||||||
IsOverridden bool
|
IsOverridden bool
|
||||||
InitUnchangedAddr net.Address
|
InitUnchangedAddr net.Address
|
||||||
InitChangedAddr net.Address
|
InitChangedAddr net.Address
|
||||||
@@ -346,30 +348,38 @@ type PacketReader struct {
|
|||||||
|
|
||||||
func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
b.Resize(0, buf.Size)
|
for {
|
||||||
n, d, err := r.PacketConnWrapper.ReadFrom(b.Bytes())
|
b.Resize(0, buf.Size)
|
||||||
if err != nil {
|
n, d, err := r.PacketConnWrapper.ReadFrom(b.Bytes())
|
||||||
b.Release()
|
if err != nil {
|
||||||
return nil, err
|
b.Release()
|
||||||
}
|
return nil, err
|
||||||
b.Resize(0, int32(n))
|
|
||||||
// if udp dest addr is changed, we are unable to get the correct src addr
|
|
||||||
// so we don't attach src info to udp packet, break cone behavior, assuming the dial dest is the expected scr addr
|
|
||||||
if !r.IsOverridden {
|
|
||||||
address := net.IPAddress(d.(*net.UDPAddr).IP)
|
|
||||||
if r.InitChangedAddr == address {
|
|
||||||
address = r.InitUnchangedAddr
|
|
||||||
}
|
}
|
||||||
b.UDP = &net.Destination{
|
b.Resize(0, int32(n))
|
||||||
Address: address,
|
|
||||||
Port: net.Port(d.(*net.UDPAddr).Port),
|
udpAddr := d.(*net.UDPAddr)
|
||||||
Network: net.Network_UDP,
|
sourceAddr := net.IPAddress(udpAddr.IP)
|
||||||
|
if isBlockedAddress(r.BlockedIPMatcher, sourceAddr) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if udp dest addr is changed, we are unable to get the correct src addr
|
||||||
|
// so we don't attach src info to udp packet, break cone behavior, assuming the dial dest is the expected scr addr
|
||||||
|
if !r.IsOverridden {
|
||||||
|
if r.InitChangedAddr == sourceAddr {
|
||||||
|
sourceAddr = r.InitUnchangedAddr
|
||||||
|
}
|
||||||
|
b.UDP = &net.Destination{
|
||||||
|
Address: sourceAddr,
|
||||||
|
Port: net.Port(udpAddr.Port),
|
||||||
|
Network: net.Network_UDP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.Counter != nil {
|
||||||
|
r.Counter.Add(int64(n))
|
||||||
|
}
|
||||||
|
return buf.MultiBuffer{b}, nil
|
||||||
}
|
}
|
||||||
if r.Counter != nil {
|
|
||||||
r.Counter.Add(int64(n))
|
|
||||||
}
|
|
||||||
return buf.MultiBuffer{b}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialDest means the dial target used in the dialer when creating conn
|
// DialDest means the dial target used in the dialer when creating conn
|
||||||
@@ -468,10 +478,8 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isBlockedAddress(w.BlockedIPMatcher, b.UDP.Address) {
|
if isBlockedAddress(w.BlockedIPMatcher, b.UDP.Address) {
|
||||||
blockedAddr := b.UDP.Address
|
|
||||||
b.Release()
|
b.Release()
|
||||||
buf.ReleaseMulti(mb)
|
continue
|
||||||
return errors.New("blocked target IP: ", blockedAddr).AtDebug()
|
|
||||||
}
|
}
|
||||||
destAddr := b.UDP.RawNetAddr()
|
destAddr := b.UDP.RawNetAddr()
|
||||||
if destAddr == nil {
|
if destAddr == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user