aresch / pyenet

A python wrapper for the ENet library
BSD 3-Clause "New" or "Revised" License
52 stars 30 forks source link

send expects strings and does not support bytes/bytearrays #34

Open ethindp opened 1 day ago

ethindp commented 1 day ago

I am implementing the Noise protocol and need to send bytes or bytearrays. However, doing so appears to crash this library because it just assumes that anything passed in is a string. To say that this is a major problem is an understatement.

BBuama commented 1 day ago

Could you provide some code snippets? Peer.send should work with bytes and bytearrays.

ethindp commented 1 day ago

Sure! As I said, I'm implementing the noise protocol, so sorry for the crypto stuff, but here is essentially the code that I use. I do this in the handler of the connect event, since I need to transmit this data as soon as possible:

# ...
while True:
    event = host.service(0)
    buf = bytearray()
    match event.type:
        case enet.EVENT_TYPE_CONNECT:
            peers.append(event.peer)
            hs_states[event.peer] = HandshakeState(
                SymmetricState(CipherState(ChaChaPolyCipher()), Blake2bHash()),
                X25519DH(),
            )
            hs_states[event.peer].initialize(
                NNHandshakePattern(), True, b""
            )
            hs_states[event.peer].write_message(b"", buf) 
            event.peer.send(
                1, Packet(bytes(buf), PACKET_FLAG_RELIABLE)
            ) # Crashes here I think
            host.flush()

It's not a full example, but I can provide more code if you need.

BBuama commented 14 hours ago

I am unsure why it is crashing for you but depending on your setup you might want to change the channel id in the Peer.send call from 1 to 0.

Server

import enet

host = enet.Host(enet.Address("localhost", 33333), 1, 0, 0)

while True:
    event = host.service(0)
    buf = bytearray([0]*100)
    match event.type:
        case enet.EVENT_TYPE_CONNECT:
            event.peer.send(0, enet.Packet(buf, enet.PACKET_FLAG_RELIABLE))
            host.flush()

Client

import enet

host = enet.Host(None, 1, 0, 0)
peer = host.connect(enet.Address("localhost", 33333), 1)

while True:
    event = host.service(0)

    match event.type:
        case enet.EVENT_TYPE_RECEIVE:
            print("got len:", event.packet.dataLength)

When I set the channel id to 1 it does not seem to send anything to the connected peer but it also does not crash the program. Setting it to 0 seemed to fix the issue.

Maybe if you can provide your operating system and python version we could debug it further

ethindp commented 13 hours ago

I'm in Python 3.12.4, OS is Windows 10 21H2 (AMD64) build 19044.4894.

BBuama commented 9 hours ago

The code I sent above worked fine on both my ubuntu 20 and windows 11. Could you maybe give me some more insight on how your setup works? Perhaps it is the way you are setting up the host. Are you also sure that buf is not empty, not that it should be a problem but might check.