diff --git a/quicp2p.nim b/quicp2p.nim index 3b9ecc9..2304953 100644 --- a/quicp2p.nim +++ b/quicp2p.nim @@ -20,8 +20,10 @@ from openssl import DLLSSLName, EVP_PKEY from posix import IOVec from strutils import parseUInt -const certChainPath = "./certs/server-certchain.pem" -const keyPath = "./certs/server-cert.key" +const serverCertChainPath = "./certs/server-certchain.pem" +const serverKeyPath = "./certs/server-cert.key" +const clientCertChainPath = "./certs/server-certchain.pem" +const clientKeyPath = "./certs/server-cert.key" type QuicP2PContext = ref object @@ -66,6 +68,7 @@ proc onReceiveReset(stream: ptr quicly_stream_t, err: cint) {.cdecl.} = proc onServerReceive(stream: ptr quicly_stream_t, offset: csize_t, src: pointer, len: csize_t) {.cdecl.} = + echo "onServerReceive" if quicly_streambuf_ingress_receive(stream, offset, src, len) != 0: return let input = quicly_streambuf_ingress_get(stream) @@ -77,6 +80,7 @@ proc onServerReceive(stream: ptr quicly_stream_t, offset: csize_t, src: pointer, proc onClientReceive(stream: ptr quicly_stream_t, offset: csize_t, src: pointer, len: csize_t) {.cdecl.} = + echo "onClientReceive" if quicly_streambuf_ingress_receive(stream, offset, src, len) != 0: return let input = quicly_streambuf_ingress_get(stream) @@ -109,13 +113,17 @@ proc usage() = proc onServerStreamOpen(self: ptr quicly_stream_open_t, stream: ptr quicly_stream_t): cint {.cdecl.} = + echo "onServerStreamOpen" result = quicly_streambuf_create(stream, sizeof(quicly_streambuf_t).csize_t) stream.callbacks = addr streamCallbacksServer proc onClientStreamOpen(self: ptr quicly_stream_open_t, stream: ptr quicly_stream_t): cint {.cdecl.} = + echo "onClientStreamOpen" result = quicly_streambuf_create(stream, sizeof(quicly_streambuf_t).csize_t) stream.callbacks = addr streamCallbacksClient + let msg = "hello server" + discard quicly_streambuf_egress_write(stream, msg.cstring, msg.len().csize_t) proc handleMsg(ctx: QuicP2PContext, msg: string, isServer: bool) = var offset: csize_t = 0 @@ -136,13 +144,15 @@ proc handleMsg(ctx: QuicP2PContext, msg: string, isServer: bool) = conn = c break if conn != nil: + echo "quicly_receive" discard quicly_receive(conn, nil, addr sockAddr, addr decoded) elif isServer: + echo "quicly_accept" discard quicly_accept(addr conn, addr ctx.quiclyCtx, nil, addr sockAddr, addr decoded, nil, addr ctx.nextCid, nil) ctx.connections.add(conn) -proc initContext(sock: AsyncSocket, +proc initContext(sock: AsyncSocket, certChainPath: string, keyPath: string, streamOpenCb: typeof(quicly_stream_open_t.cb)): QuicP2PContext = var tlsCtx = ptls_context_t(randomBytes: ptlsOpensslRandomBytes, @@ -177,33 +187,40 @@ proc sendPackets(ctx: QuicP2PContext) = dgramsBuf.len().csize_t) case sendResult: of 0: - for d in dgrams: - var sockLen = quicly_get_socklen(addr dstAddr.sa) - asyncCheck sendTo(ctx.sock.getFd().AsyncFD, d.iov_base, d.iov_len.int, - addr dstAddr.sa, sockLen) + if dgramCount > 0: + echo &"sending {dgramCount} datagrams" + for i in 0 .. dgramCount - 1: + #echo "dstAddr.sa: ", dstAddr.sa + var sockLen = quicly_get_socklen(addr dstAddr.sa) + asyncCheck sendTo(ctx.sock.getFd().AsyncFD, dgrams[i].iov_base, + dgrams[i].iov_len.int, addr dstAddr.sa, sockLen) of QUICLY_ERROR_FREE_CONNECTION: ctx.connections.del(ctx.connections.find(c)) quicly_free(c) else: raise newException(ValueError, &"quicly_send returned {sendResult}") -proc receive(ctx: QuicP2PContext, sock: AsyncSocket, isServer: bool) {.async.} = +proc receive(ctx: QuicP2PContext, isServer: bool) {.async.} = while true: - let msg = await sock.recv(BufferSize) - handleMsg(ctx, msg, isServer) + let msg = await ctx.sock.recv(BufferSize) + echo &"received {msg.len()} bytes" + if msg.len > 0: + handleMsg(ctx, msg, isServer) proc main() = var ctx: QuicP2PContext - let sock = newAsyncSocket(sockType = SOCK_DGRAM, protocol = IPPROTO_UDP) + let sock = newAsyncSocket(sockType = SOCK_DGRAM, protocol = IPPROTO_UDP, + buffered = false) case paramCount(): of 1: let portNumber = paramStr(1).parseUInt() if portNumber > uint16.high: usage() quit(1) - ctx = initContext(sock, onServerStreamOpen) sock.bindAddr(Port(portNumber)) - asyncCheck receive(ctx, sock, true) + ctx = initContext(sock, serverCertChainPath, serverKeyPath, + onServerStreamOpen) + asyncCheck receive(ctx, true) of 2: let hostname = paramStr(1) @@ -211,7 +228,8 @@ proc main() = if portNumber > uint16.high: usage() quit(1) - ctx = initContext(sock, onClientStreamOpen) + ctx = initContext(sock, clientCertChainPath, clientKeyPath, + onClientStreamOpen) var conn: ptr quicly_conn_t let hostent = getHostByName(hostname) if hostent.addrList.len == 0: @@ -231,7 +249,7 @@ proc main() = ctx.connections.add(conn) var stream: ptr quicly_stream_t discard quicly_open_stream(conn, addr stream, 0) - asyncCheck receive(ctx, sock, false) + asyncCheck receive(ctx, false) else: usage() @@ -239,7 +257,6 @@ proc main() = while true: let nextTimeout = ctx.getRelativeTimeout() - echo "nextTimeout: ", nextTimeout poll(nextTimeout) ctx.sendPackets()