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

OOB and disOOB implementation #2

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open

OOB and disOOB implementation #2

wants to merge 21 commits into from

Conversation

siriusfreak
Copy link
Owner

No description provided.

Copy link

@fortuna fortuna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very exciting. Thanks for the contribution!

oobData := []byte{w.oobByte}
var flags int
if w.disOOB {
flags = syscall.MSG_OOB | syscall.MSG_DONTROUTE // Additional flag for disOOB mode
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see MSG_OOB in the windows documentation of syscall. I believe you need https://pkg.go.dev/golang.org/x/sys/windows.

It's important for us to support Windows and have cross-platform support, so providers can specify a single strategy for all platforms.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

return nil, err
}
// Wrap connection with OOB and/or disOOB writer based on configuration
return transport.WrapConn(innerConn, innerConn, NewOOBWriter(innerConn, d.oobPosition, d.oobByte, d.disOOB)), nil
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should test if innerConn is a *net.TCPConn here, before wrapping.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

// NewOOBWriter creates an [io.Writer] that sends an OOB byte at the specified "oobPosition".
// If disOOB is enabled, it will apply the --disOOB strategy.
// "oobByte" specifies the value of the byte to send out-of-band.
func NewOOBWriter(writer io.Writer, oobPosition int64, oobByte byte, disOOB bool) io.Writer {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be any writer, it must be a *TCPConn. Let's make that explicit.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep this in the x folder for now. We need comprehensive tests and an expectation of stability to be in the main SDK module. We will "graduate" experimental packages from x as they become stable and tested.

That will also remove the need for the replace directive in your go.mod file.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

alim-shapiev pushed a commit that referenced this pull request Nov 3, 2024
Copy link

@fortuna fortuna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for the contribution.

Can you rebase this PR and send it to the official repository?

x/oob/ttl.go Outdated
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used

x/oob/writer.go Outdated
}
}

err = w.send(firstPart, 0x01)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flag shouldn't be hardcoded for readability and portability.
use unix.MSG_OOB and windows.MSG_OOB instead from the x/sys package.
Probably helpful to define a portable MSG_OOB flags somewhere in your code.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

x/oob/writer.go Outdated
return &oobWriter{conn: conn, sd: sd, oobPosition: oobPosition, oobByte: oobByte, disOOB: disOOB, delay: delay}
}

func (w *oobWriterReaderFrom) ReadFrom(source io.Reader) (int64, error) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove ReadFrom, since it doesn't support it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

oobByte byte
oobPosition int64
disOOB bool
delay time.Duration
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the delay really needed? I found the TCP writes to be quite consistent and never had issues without the delay.
For simplicity, I would only add it if proven needed in Go.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Delay is essential.

static ssize_t send_oob(int sfd, char *buffer,
        ssize_t n, long pos, const char *c)
{
    char rchar = buffer[pos];
    buffer[pos] = c[1] ? c[0] : 'a';
    
    ssize_t len = send(sfd, buffer, pos + 1, MSG_OOB);
    buffer[pos] = rchar;
    
    if (len < 0) {
        uniperror("send");
        return -1;
    }
    wait_send_if_support(sfd);
    
    len--;
    if (len != pos) {
        return len;
    }
    return len;
}

This is a little bit complex implementation in byeDPI that works only on linux. So now it is only delay.

x/oob/writer.go Outdated
// "oobByte" specifies the value of the byte to send out-of-band.
func NewWriter(
conn *net.TCPConn,
sd SocketDescriptor,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to pass a socket descriptor. Use TCPConn.SyscallConn().Write() instead.
You shouldn't be holding socket file descriptors, because they may not be valid anymore. Go has special logic to keep them alive: https://cs.opensource.google/go/go/+/master:src/net/rawconn.go;l=57;drc=9088883cf4a5181cf796c968bbce5a5bc3edc7ab

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

x/oob/writer.go Outdated Show resolved Hide resolved

var oldTTL int
if w.disOOB {
w.setTTL.Do(func() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this can be accomplished by overlaying disorder on top of OOB.
Something like: oob:10:X | disorder:10

But we can figure that out later.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In https://github.com/hufrea/byedpi/blob/a6ee6ddb924fbed33e3c4569d2ba45dcdebfc61a/desync.c#L526 this is different strategies. I will test if it possible to combine with same effect

var err error

if w.oobPosition > 0 && w.oobPosition < int64(len(data)) {
firstPart := data[:w.oobPosition+1]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will trigger index out of bounds if len(data) == oobPosition+1.

You may consider using https://linux.die.net/man/2/sendmsg, which supports the io vector, so you can pass two buffers for an atomic write.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

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

Successfully merging this pull request may close these issues.

2 participants