mihomo/transport/tuic/v5/packet.go

210 lines
4.1 KiB
Go
Raw Normal View History

2023-06-12 17:44:22 +08:00
package v5
2022-11-28 17:09:25 +08:00
import (
2023-06-12 17:44:22 +08:00
"errors"
2022-11-28 17:09:25 +08:00
"net"
"sync"
"time"
"github.com/Dreamacro/clash/common/atomic"
2022-11-28 17:09:25 +08:00
N "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/common/pool"
"github.com/Dreamacro/clash/transport/tuic/common"
2022-11-28 17:09:25 +08:00
2023-06-12 17:44:22 +08:00
"github.com/metacubex/quic-go"
"github.com/zhangyunhao116/fastrand"
)
2022-11-28 17:09:25 +08:00
type quicStreamPacketConn struct {
2023-06-12 17:44:22 +08:00
connId uint16
2022-11-28 17:09:25 +08:00
quicConn quic.Connection
inputConn *N.BufferedConn
udpRelayMode common.UdpRelayMode
2022-11-28 17:09:25 +08:00
maxUdpRelayPacketSize int
deferQuicConnFn func(quicConn quic.Connection, err error)
closeDeferFn func()
writeClosed *atomic.Bool
2022-11-28 17:09:25 +08:00
closeOnce sync.Once
closeErr error
closed bool
2023-06-12 17:44:22 +08:00
deFragger
2022-11-28 17:09:25 +08:00
}
func (q *quicStreamPacketConn) Close() error {
q.closeOnce.Do(func() {
q.closed = true
q.closeErr = q.close()
})
return q.closeErr
}
func (q *quicStreamPacketConn) close() (err error) {
if q.closeDeferFn != nil {
defer q.closeDeferFn()
}
if q.deferQuicConnFn != nil {
defer func() {
2022-11-28 17:09:25 +08:00
q.deferQuicConnFn(q.quicConn, err)
}()
}
2022-11-28 17:09:25 +08:00
if q.inputConn != nil {
_ = q.inputConn.Close()
q.inputConn = nil
buf := pool.GetBuffer()
defer pool.PutBuffer(buf)
err = NewDissociate(q.connId).WriteTo(buf)
if err != nil {
return
}
var stream quic.SendStream
stream, err = q.quicConn.OpenUniStream()
if err != nil {
return
}
_, err = buf.WriteTo(stream)
if err != nil {
return
}
err = stream.Close()
if err != nil {
return
}
}
return
}
func (q *quicStreamPacketConn) SetDeadline(t time.Time) error {
//TODO implement me
return nil
}
func (q *quicStreamPacketConn) SetReadDeadline(t time.Time) error {
if q.inputConn != nil {
return q.inputConn.SetReadDeadline(t)
}
return nil
}
func (q *quicStreamPacketConn) SetWriteDeadline(t time.Time) error {
//TODO implement me
return nil
}
func (q *quicStreamPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
if q.inputConn != nil {
2023-06-12 17:44:22 +08:00
for {
var packet Packet
packet, err = ReadPacket(q.inputConn)
if err != nil {
return
}
if packetPtr := q.deFragger.Feed(packet); packetPtr != nil {
n = copy(p, packet.DATA)
addr = packetPtr.ADDR.UDPAddr()
return
}
2022-11-28 17:09:25 +08:00
}
} else {
err = net.ErrClosed
}
return
}
func (q *quicStreamPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) {
if q.inputConn != nil {
2023-06-12 17:44:22 +08:00
for {
var packet Packet
packet, err = ReadPacket(q.inputConn)
if err != nil {
return
}
if packetPtr := q.deFragger.Feed(packet); packetPtr != nil {
data = packetPtr.DATA
addr = packetPtr.ADDR.UDPAddr()
return
}
}
} else {
err = net.ErrClosed
}
return
}
2022-11-28 17:09:25 +08:00
func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
2023-06-12 17:44:22 +08:00
if len(p) > 0xffff { // uint16 max
return 0, quic.ErrMessageTooLarge(0xffff)
2022-11-28 17:09:25 +08:00
}
if q.closed {
return 0, net.ErrClosed
}
if q.writeClosed != nil && q.writeClosed.Load() {
_ = q.Close()
return 0, net.ErrClosed
}
if q.deferQuicConnFn != nil {
defer func() {
2022-11-28 17:09:25 +08:00
q.deferQuicConnFn(q.quicConn, err)
}()
}
2022-11-28 17:09:25 +08:00
buf := pool.GetBuffer()
defer pool.PutBuffer(buf)
address, err := NewAddressNetAddr(addr)
2022-11-28 17:09:25 +08:00
if err != nil {
return
}
2023-06-12 17:44:22 +08:00
pktId := uint16(fastrand.Uint32())
packet := NewPacket(q.connId, pktId, 1, 0, uint16(len(p)), address, p)
2022-11-28 17:09:25 +08:00
switch q.udpRelayMode {
case common.QUIC:
2023-06-12 17:44:22 +08:00
err = packet.WriteTo(buf)
if err != nil {
return
}
2022-11-28 17:09:25 +08:00
var stream quic.SendStream
stream, err = q.quicConn.OpenUniStream()
if err != nil {
return
}
defer stream.Close()
_, err = buf.WriteTo(stream)
if err != nil {
return
}
default: // native
2023-06-12 17:44:22 +08:00
if len(p) > q.maxUdpRelayPacketSize {
err = fragWriteNative(q.quicConn, packet, buf, q.maxUdpRelayPacketSize)
if err != nil {
return
}
}
err = packet.WriteTo(buf)
if err != nil {
return
}
2023-03-12 19:03:03 +08:00
data := buf.Bytes()
err = q.quicConn.SendMessage(data)
2023-06-12 17:44:22 +08:00
var tooLarge quic.ErrMessageTooLarge
if errors.As(err, &tooLarge) {
err = fragWriteNative(q.quicConn, packet, buf, int(tooLarge)-PacketOverHead)
}
2022-11-28 17:09:25 +08:00
if err != nil {
return
}
}
n = len(p)
return
}
func (q *quicStreamPacketConn) LocalAddr() net.Addr {
return q.quicConn.LocalAddr()
2022-11-28 17:09:25 +08:00
}
var _ net.PacketConn = (*quicStreamPacketConn)(nil)