Code Monkey home page Code Monkey logo

go-raknet's People

Contributors

deepsourcebot avatar fwflunky avatar haveachin avatar josiahwhite avatar justtaldevelops avatar meme avatar sandertv avatar smell-of-curry avatar t14raptor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

go-raknet's Issues

Not reading RakNet packet results in freezing of server

Currently, when packets are not immediately read from a *raknet.Conn, the server will be blocked until this happens anyway. Having a single client block until the next packet is acceptable, but blocking the entire server is unacceptable, as packets that are not instantly handled could directly result in a considerable slowdown for all other clients.

connectedPing is sent 100 times every 4 seconds

I'm new to go and I've no experience with go tickers but I'm sure this condition is true 100 times every 4 seconds by default and it's not supposed to be.
t.Unix() is the current time in seconds and will be the same 100 times every second

Slow connections can block other clients from joining for up to 10 seconds

The Listener.Accept method (https://github.com/Sandertv/go-raknet/blob/master/listener.go#L79) currently does not obtain connections that are ready right away. It gets a connection that still needs to do the RakNet connection sequence, which poses a problem if the client has a poor connection. Listener.Accept can block up to 10 seconds, after which it times out and tries the next connection, until a new client can be accepted. This is a major issue for frequent connection attempts with a high latency.

Proxy and MTU matching

Hello, I believe I found a bug and will submit a patch soon.

The bug is this:

When using the project as proxy the MTU may be different between clients and server, and that will break the raknet protocol, that is MTU sensitive, because packets between server and clients in the example proxy are passed as raw data, they are not assembled, while the MTUs are negotiated between proxy and server and proxy and clients inside the raknet handshake.

The solution I found was to connect to the server first, get the MTU of the server, and disconnect. Wait for client connections but limiting max MTU with client to match MTU of the server, and then when opening the connection to the server after a client connects, limit server MTU with client's. This will cover usecases where either client or server have bigger MTU than the other, by limiting the MTU of the connection to the least of the two sides.

Decide if Listener.DisableCookies field should go

As of v1.14.0, go-raknet uses cookies to prevent IP spoofing attacks. These cookies are very inexpensive to generate and check. Some server providers (OVH specifically) have built-in protection against these kinds of attacks however, which breaks when used in combination with these cookies, meaning clients are entirely unable to connect.

To avert this, there is a DisableCookies field in go-raknet, but ideally this should not exist. People have messaged OVH to let them know of this issue so this may be fixed in the future. That would mean removing the field in go-raknet, which is a backwards incompatible change (so not great).

Remove this field before release?

Connection timeout

I just updated go-raknet to the latest release available and this error occurs:

panic: error establishing a connection: connection timed out

goroutine 1 [running]:
main.main()
	/home/gio/Desktop/test/gophertunnel/main.go:39 +0x56b

You can reproduce by using the proxy from the gophertunnel repo and connecting to "hivebedrock.network:19132"

Before the update I was using the one from this commit and it worked

This error is from here

I don't know why the raknet connection is timing out, the ConnectionRequestAccepted is received correctly.

Acknowledgement packets not written correctly

For some reason, the recordCount is set to 1 from the start while writing an acknowledgement packet, resulting in a recordCount that is too high. If the packet is read, this will result in an overflow, because it expects another record to be available.

RakNet Security layer is not supported

Trying to connect to a server which uses the RakNet security flag (In OpenConnectionReply1) causes a timeout. While I am not 100% sure that the timeout is not caused by some other error in go-raknet other RakNet libraries failed because of the servers usage of the security flag (See CloudburstMC/Network#37). Connecting to the server with Bedrock Edition (or https://github.com/extremeheat/fb-raknet) works fine since both use the original RakNet.

Reproduceable example code:

package main

import (
	"github.com/sandertv/go-raknet"
	"time"
)

func main() {
	conn, err := raknet.DialTimeout("play.timecrack.net:19132", time.Duration(5)*time.Second)
	if err != nil {
		panic(err.Error())
	}
	defer func(conn *raknet.Conn) {
		err := conn.Close()
		if err != nil {
			panic(err.Error())
		}
	}(conn)

	println("Connected")
}

Replace 'packets' channel in raknet.Conn

go-raknet uses a buffered channel for storing and retrieving incoming packets from a connection. This channel needs to have a large buffered size to prevent an entire Listener from being blocked if this channel is full, which is not ideal. The channel is currently created with a size of 512: https://github.com/Sandertv/go-raknet/blob/master/conn.go#L103

This channel is responsible for roughly a third of allocations/in use memory of go-raknet and remains a potential attack vector against listeners.

This channel should be replaced with a different (dynamic) approach that doesn't require buffering beforehand and doesn't block when the buffer is full.

Limit of concurrent splits should be a lot smaller than 256

go-raknet/conn.go

Lines 666 to 669 in fbd2ad1

const maxSplitCount = 256
if (p.splitCount > maxSplitCount || len(conn.splits) > maxSplitCount) && conn.limits {
return fmt.Errorf("split count %v (%v active) exceeds the maximum %v", p.splitCount, len(conn.splits), maxSplitCount)
}

Theoretically speaking the client should never send more than one or two unique split IDs, and go-raknet allows up to 256 at one time. This could be abused to keep ~97mb (256*255*1492) of data in memory from one connection if they don't send the last split for each packet.

Packet decode

how do i get a raklib packet from the buffer string?
!without connection, only from buffer string!

Error discovering MTU

This happens randomly on different servers, this one in particular, on lbsg:

panic: error discovering MTU size: read udp myIP:46257->lbsgIP:19132: read: message too long

Also, the way the MTU is discovered (subtracting 40 to the size every 1/2 second) it's not the same way minecraft itself does it. Minecraft only uses 3 MTU sizes: 1492, 1200, 576

Packet error

When i use conn.Write(), it causes the following errors
2022/08/25 19:50:01 error handling packet: error handling packet in datagram: error handling packet: error measuring rtt: ping timestamp is in the future
....

Just byte send testing is ok.

read: message too long

This happens on some servers, mostly nethergames, but not all of the time

It happens with raknet.Dial but not with net.Dial("udp", addr)
It will happen the first time dialing, and then not happen for a while, unless I turn off my wifi and turn it back on on my PC

It occurs at:

n, err := state.conn.Read(b)

Using the terminal ping command and disabling fragmentation
image

Packets are sometimes unnecessarily resent in a loop

Currently a packet is resent if no ACK is received before Round-Trip Time + 10ms since it was sent.
This is "fine" for most of the servers sending ACKs every 10ms (PocketMine)
But there are some servers, like SteadFast2 which instead will send ACKs every 25ms

The RTT is not perfect, changes continuously overtime and only indicates a rough estimate of the ping latency which is different than the ACK one

So, on some servers packets will be resent forever since it's impossible to receive an ACK in time.

The effect of this is not noticeable because the client and server will automatically discard duplicate packets.

Protocol version changing

How can I change the protocol version used without creating a fork? I saw this comment, but I still don't know how to change it

img

not compilable and executable

When trying to execute a executable generated with this example code it fails:

package main

import (
	"github.com/sandertv/go-raknet"
)

func main() {
	listener, _ := raknet.Listen("0.0.0.0:19132")
	listener.PongData([]byte("MCPE;Dedicated Server;120;1.20.50;1000;9999;13253860896781930865;Bedrock level;Survival;1;19132;19133;"))

	defer listener.Close()
	for {
		conn, _ := listener.Accept()

		b := make([]byte, 1024*1024*4)

		_, _ = conn.Read(b)
	}
}

The following error:

C:\Users\current_user\Test>Test.exe
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x9c62a9]

goroutine 1 [running]:
github.com/sandertv/go-raknet.(*Listener).PongData(0x0?, {0xc0000c6000?, 0x0?, 0x9ff13d?})
        C:/Users/current_user/go/pkg/mod/github.com/sandertv/[email protected]/listener.go:139 +0x29
main.main()
        C:/Users/current_user/Test/main.go:9 +0x88

error reading unconnected ping: unexpected EOF

two logs were triggered:
2023/07/27 11:48:03 listener: error handling packet (addr = x.x.x.x:46926): error reading unconnected ping: unexpected EOF
2023/07/28 11:09:03 listener: error handling packet (addr = x.x.x.x:46926): error reading unconnected ping: EOF

those logs might be the reason for these two players being kept on the (dragonfly) server, even while disconnected:
image
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.