Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

udp associate port and address have the problem #2

Closed
grayscott opened this issue May 21, 2020 · 28 comments
Closed

udp associate port and address have the problem #2

grayscott opened this issue May 21, 2020 · 28 comments

Comments

@grayscott
Copy link

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
Copy link
Author

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
}

@txthinking
Copy link
Owner

What is the 'problem'?

@grayscott
Copy link
Author

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

@grayscott
Copy link
Author

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
Copy link
Author

this is change function

@txthinking
Copy link
Owner

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

@grayscott
Copy link
Author

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

@txthinking
Copy link
Owner

txthinking commented May 25, 2020 via email

@txthinking
Copy link
Owner

txthinking commented May 25, 2020 via email

@txthinking
Copy link
Owner

txthinking commented May 25, 2020 via email

@grayscott
Copy link
Author

image
this is the tcpconnect description

@grayscott
Copy link
Author

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

@grayscott
Copy link
Author

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

@txthinking
Copy link
Owner

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
Copy link
Owner

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

@grayscott
Copy link
Author

ok

@txthinking
Copy link
Owner

txthinking commented May 25, 2020

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

@grayscott
Copy link
Author

image

@grayscott
Copy link
Author

but your read is block read full two bytes

@txthinking
Copy link
Owner

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

@grayscott
Copy link
Author

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

@grayscott
Copy link
Author

I can't push my code

@grayscott
Copy link
Author

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

@txthinking
Copy link
Owner

@txthinking
Copy link
Owner

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

@grayscott
Copy link
Author

ok, 3Q

@txthinking
Copy link
Owner

txthinking commented May 26, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants