@@ -365,7 +365,7 @@ func (c *SshUdpClient) DialUDP(network, addr string, timeout time.Duration) (Pac
365365 return & sshUdpPacketConn {packetConn : conn , client : c }, nil
366366}
367367
368- // Listen requests the remote peer open a listening socket on addr
368+ // Listen requests the remote peer to open a listening socket on addr
369369func (c * SshUdpClient ) Listen (network , addr string ) (net.Listener , error ) {
370370 stream , err := c .newStream ("listen" )
371371 if err != nil {
@@ -387,6 +387,28 @@ func (c *SshUdpClient) Listen(network, addr string) (net.Listener, error) {
387387 return & sshUdpListener {client : c , stream : stream }, nil
388388}
389389
390+ // ListenUDP requests the remote peer to open a UDP listening endpoint on addr
391+ func (c * SshUdpClient ) ListenUDP (network , addr string ) (PacketListener , error ) {
392+ stream , err := c .newStream ("listen-udp" )
393+ if err != nil {
394+ return nil , err
395+ }
396+ msg := listenUdpMessage {
397+ Net : network ,
398+ Addr : addr ,
399+ }
400+ if err := sendMessage (stream , & msg ); err != nil {
401+ _ = stream .Close ()
402+ return nil , fmt .Errorf ("send listen udp message failed: %w" , err )
403+ }
404+ if err := recvError (stream ); err != nil {
405+ _ = stream .Close ()
406+ return nil , err
407+ }
408+ c .exitWG .Add (1 )
409+ return & sshUdpPacketListener {client : c , stream : stream }, nil
410+ }
411+
390412// HandleChannelOpen returns a channel on which NewChannel requests
391413func (c * SshUdpClient ) HandleChannelOpen (channelType string ) <- chan ssh.NewChannel {
392414 c .channelMutex .Lock ()
@@ -1249,3 +1271,43 @@ func (c *sshUdpPacketConn) Close() error {
12491271 c .client .exitWG .Done ()
12501272 return err
12511273}
1274+
1275+ type sshUdpPacketListener struct {
1276+ client * SshUdpClient
1277+ stream Stream
1278+ closed atomic.Bool
1279+ }
1280+
1281+ func (l * sshUdpPacketListener ) AcceptUDP () (PacketConn , error ) {
1282+ var msg acceptUdpMessage
1283+ if err := recvMessage (l .stream , & msg ); err != nil {
1284+ return nil , fmt .Errorf ("recv accept udp message failed: %w" , err )
1285+ }
1286+ stream , err := l .client .newStream ("accept-udp" )
1287+ if err != nil {
1288+ return nil , err
1289+ }
1290+
1291+ conn := newPacketConn (stream , msg .ID , l .client .protoClient .getUdpForwarder (), l .client .networkProxy .serverChecker )
1292+
1293+ if err := sendMessage (stream , & msg ); err != nil {
1294+ _ = stream .Close ()
1295+ return nil , fmt .Errorf ("send accept udp message failed: %w" , err )
1296+ }
1297+ if err := recvError (stream ); err != nil {
1298+ _ = stream .Close ()
1299+ return nil , err
1300+ }
1301+
1302+ l .client .exitWG .Add (1 )
1303+ return & sshUdpPacketConn {packetConn : conn , client : l .client }, nil
1304+ }
1305+
1306+ func (l * sshUdpPacketListener ) Close () error {
1307+ if ! l .closed .CompareAndSwap (false , true ) {
1308+ return nil
1309+ }
1310+ err := l .stream .Close ()
1311+ l .client .exitWG .Done ()
1312+ return err
1313+ }
0 commit comments