socks5 icon indicating copy to clipboard operation
socks5 copied to clipboard

udp associate port and address have the problem

Open grayscott opened this issue 5 years ago • 28 comments

Describe actual behavior

What is your expected behavior

Specifications like the version of the project, operating system, or hardware

Steps to reproduce the problem

grayscott avatar May 21 '20 05:05 grayscott

func (r *Reply) WriteTo(w io.Writer) (int64, error) { var n int i, err := w.Write([]byte{r.Ver, r.Rep, r.Rsv, r.Atyp}) n = n + i if err != nil { return int64(n), err } i, err = w.Write(r.BndAddr) n = n + i if err != nil { return int64(n), err } i, err = w.Write(r.BndPort) n = n + i if err != nil { return int64(n), err } if Debug { log.Printf("Sent Reply: %#v %#v %#v %#v %#v %#v\n", r.Ver, r.Rep, r.Rsv, r.Atyp, r.BndAddr, r.BndPort) } return int64(n), nil }

grayscott avatar May 21 '20 05:05 grayscott

What is the 'problem'?

txthinking avatar May 22 '20 06:05 txthinking

you write associate ack data in three time, client will read loss data

grayscott avatar May 25 '20 09:05 grayscott

func (r *Reply) WriteTo(w io.Writer) (int64, error) { var n int buffer := bytes.NewBuffer([]byte{r.Ver, r.Rep, r.Rsv, r.Atyp}) buffer.Write(r.BndAddr) buffer.Write(r.BndPort) i, err := w.Write(buffer.Bytes()) n = n + i if err != nil { return int64(n), err } fmt.Printf("debug value:%t", Debug) if Debug { log.Printf("Sent Reply: %#v %#v %#v %#v %#v %#v\n", r.Ver, r.Rep, r.Rsv, r.Atyp, r.BndAddr, r.BndPort) } return int64(n), nil }

grayscott avatar May 25 '20 09:05 grayscott

this is change function

grayscott avatar May 25 '20 09:05 grayscott

TCP is a stream protocol, so write([0x01]), write([0x02]) is same with write([0x01, 0x02])

txthinking avatar May 25 '20 09:05 txthinking

but the result is not that on my pc and if you socket set so_nodelay flag the result is separate

grayscott avatar May 25 '20 10:05 grayscott

Can you show some related read/write code?

On Mon, May 25, 2020 at 6:25 PM grayscot [email protected] wrote:

but the result is not that on my pc and if you socket set so_nodelay flag the result is separate

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/txthinking/socks5/issues/2#issuecomment-633501774, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJPFT44GED25PA4BF2T54LRTJBRRANCNFSM4NGRMSVQ .

txthinking avatar May 25 '20 10:05 txthinking

Any why dont you use https://github.com/txthinking/socks5/blob/master/client_side.go#L163 ?

On Mon, May 25, 2020 at 6:40 PM Cloud [email protected] wrote:

Can you show some related read/write code?

On Mon, May 25, 2020 at 6:25 PM grayscot [email protected] wrote:

but the result is not that on my pc and if you socket set so_nodelay flag the result is separate

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/txthinking/socks5/issues/2#issuecomment-633501774, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJPFT44GED25PA4BF2T54LRTJBRRANCNFSM4NGRMSVQ .

txthinking avatar May 25 '20 10:05 txthinking

  1. How to set so_nodelay true or fase?
  2. What does the 'package is separate three slice' mean?

On Mon, May 25, 2020 at 7:08 PM grayscot [email protected] wrote:

just use your code,but have problem with udp associate response, the package is separate three slice

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/txthinking/socks5/issues/2#issuecomment-633518462, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJPFT2J7RBNI7MY2XDVIQ3RTJGTTANCNFSM4NGRMSVQ .

txthinking avatar May 25 '20 11:05 txthinking

image this is the tcpconnect description

grayscott avatar May 25 '20 11:05 grayscott

so that you three times to write socket will send three packages in network

grayscott avatar May 25 '20 11:05 grayscott

could you give me privilege to push the code, there has two to fault with udp proxy

grayscott avatar May 25 '20 11:05 grayscott

Can you copy this code and run, then paste the output:

package main

import (
	"io"
	"log"
	"net"
	"time"
)

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	a, err := net.ResolveTCPAddr("tcp", "127.0.0.1:9999")
	if err != nil {
		log.Println(err)
		return
	}
	go func() {
		s, err := net.ListenTCP("tcp", a)
		if err != nil {
			log.Println(err)
			return
		}
		for {
			conn, err := s.AcceptTCP()
			if err != nil {
				log.Println(err)
				return
			}
			log.Println("server set no delay", conn.SetNoDelay(true))
			n, err := conn.Write([]byte{0x01})
			if err != nil {
				log.Println(err)
				return
			}
			log.Println("server write to client length", n, "data", []byte{0x01})
			n, err = conn.Write([]byte{0x02})
			if err != nil {
				log.Println(err)
				return
			}
			log.Println("server write to client length", n, "data", []byte{0x02})
			conn.Close()
		}
	}()

	time.Sleep(3 * time.Second)

	conn, err := net.DialTCP("tcp", nil, a)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("client set no delay", conn.SetNoDelay(true))
	b := make([]byte, 2)
	n, err := io.ReadFull(conn, b)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("client read from server length", n, "data", b)

	time.Sleep(3 * time.Second)
}

Here is output I got:

2020/05/25 20:09:28 a.go:54: client set no delay <nil>
2020/05/25 20:09:28 a.go:30: server set no delay <nil>
2020/05/25 20:09:28 a.go:36: server write to client length 1 data [1]
2020/05/25 20:09:28 a.go:42: server write to client length 1 data [2]
2020/05/25 20:09:28 a.go:61: client read from server length 2 data [1 2]

txthinking avatar May 25 '20 12:05 txthinking

Yes you and anyone can send PR, don't need my authorization

txthinking avatar May 25 '20 12:05 txthinking

ok

grayscott avatar May 25 '20 12:05 grayscott

Can you copy this code and run, then paste the output:

package main

import (
	"io"
	"log"
	"net"
	"time"
)

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	a, err := net.ResolveTCPAddr("tcp", "127.0.0.1:9999")
	if err != nil {
		log.Println(err)
		return
	}
	go func() {
		s, err := net.ListenTCP("tcp", a)
		if err != nil {
			log.Println(err)
			return
		}
		for {
			conn, err := s.AcceptTCP()
			if err != nil {
				log.Println(err)
				return
			}
			log.Println("server set no delay", conn.SetNoDelay(true))
			n, err := conn.Write([]byte{0x01})
			if err != nil {
				log.Println(err)
				return
			}
			log.Println("server write to client length", n, "data", []byte{0x01})
			n, err = conn.Write([]byte{0x02})
			if err != nil {
				log.Println(err)
				return
			}
			log.Println("server write to client length", n, "data", []byte{0x02})
			conn.Close()
		}
	}()

	time.Sleep(3 * time.Second)

	conn, err := net.DialTCP("tcp", nil, a)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("client set no delay", conn.SetNoDelay(true))
	b := make([]byte, 2)
	n, err := io.ReadFull(conn, b)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("client read from server length", n, "data", b)

	time.Sleep(3 * time.Second)
}

Here is output I got:

2020/05/25 20:09:28 a.go:54: client set no delay <nil>
2020/05/25 20:09:28 a.go:30: server set no delay <nil>
2020/05/25 20:09:28 a.go:36: server write to client length 1 data [1]
2020/05/25 20:09:28 a.go:42: server write to client length 1 data [2]
2020/05/25 20:09:28 a.go:61: client read from server length 2 data [1 2]

This is minimal tcp read write, about your question

txthinking avatar May 25 '20 12:05 txthinking

image

grayscott avatar May 25 '20 12:05 grayscott

but your read is block read full two bytes

grayscott avatar May 25 '20 12:05 grayscott

Yes, this is what func NewReplyFrom(r io.Reader) (*Reply, error) { does

txthinking avatar May 25 '20 12:05 txthinking

git.exe push --progress "origin" master:master remote: Permission to txthinking/socks5.git denied to grayscott.

grayscott avatar May 25 '20 12:05 grayscott

I can't push my code

grayscott avatar May 25 '20 12:05 grayscott

my socks5 client is C++ code which will not block socket to read giving bytes

grayscott avatar May 25 '20 12:05 grayscott

Please fork and https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork

txthinking avatar May 25 '20 12:05 txthinking

Does this useful? https://stackoverflow.com/questions/12773509/read-is-not-blocking-in-socket-programming

txthinking avatar May 25 '20 12:05 txthinking

I recommend use this go socks5 lib to build client.

Build and Use Go Packages as C Libraries

https://medium.com/swlh/build-and-use-go-packages-as-c-libraries-889eb0c19838

txthinking avatar May 25 '20 13:05 txthinking

ok, 3Q

grayscott avatar May 26 '20 01:05 grayscott

I made a c client to connect to the above server,

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
        int fd = 0;
        struct sockaddr_in a;
        if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
                return 1;
        }
        memset(&a, '0', sizeof(a));
        a.sin_family = AF_INET;
        a.sin_port = htons(9999);
        if(inet_pton(AF_INET, "127.0.0.1", &a.sin_addr)<=0){
                return 1;
        }
        if( connect(fd, (struct sockaddr *)&a, sizeof(a)) < 0){
                return 1;
        }

        int got = 0, n = 0;
        char b[2];
        memset(b, '0',sizeof(b));
        for(;n < 2;){
        n = read(fd, b+got, 2-got);
        if (n == 0){
            printf("closed\n");
            break;
        }
        if (n < -1){
            printf("error\n");
            break;
        }
        printf("read from server length %d\n", n);
        got += n;
        }
        return 0;
}

Run multi times:

// gcc a.c -o a
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 1
read from server length 1
closed
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 1
read from server length 1
closed
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 2
firsts-MacBook-Pro:Downloads tx$ ./a
read from server length 1
read from server length 1
closed

Every things is ok. so I closed this issue

txthinking avatar May 26 '20 02:05 txthinking