A QUIC implementation in pure go

A QUIC implementation in pure Go

PkgGoDev Travis Build Status CircleCI Build Status Windows Build Status Code Coverage

quic-go is an implementation of the QUIC protocol in Go. It implements the IETF QUIC draft-29 and draft-32.

Version compatibility

Since quic-go is under active development, there's no guarantee that two builds of different commits are interoperable. The QUIC version used in the master branch is just a placeholder, and should not be considered stable.

When using quic-go as a library, please always use a tagged release. Only these releases use the official draft version numbers.

Guides

We currently support Go 1.14+, with Go modules support enabled.

Running tests:

go test ./...

QUIC without HTTP/3

Take a look at this echo example.

Usage

As a server

See the example server. Starting a QUIC server is very similar to the standard lib http in go:

http.Handle("/", http.FileServer(http.Dir(wwwDir)))
http3.ListenAndServeQUIC("localhost:4242", "/path/to/cert/chain.pem", "/path/to/privkey.pem", nil)

As a client

See the example client. Use a http3.RoundTripper as a Transport in a http.Client.

http.Client{
  Transport: &http3.RoundTripper{},
}

Contributing

We are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with help wanted. If you have any questions, please feel free to reach out by opening an issue or leaving a comment.

Comments
  • http3 post request with body failed

    http3 post request with body failed

    this problem origin publish in caddy issue, but i think it is a quic go problems, more info:https://github.com/caddyserver/caddy/issues/3429

    post request has body so can not return response. you can reference this link: https://github.com/caddyserver/caddy/issues/3429

    i am a co-worker with @majc08149 , i find problem reason and code. But I do not know how to modify? @mholt

    I paste problem code : file->net/http/transfer.go:371

    if t.BodyCloser != nil { if err := t.BodyCloser.Close(); err != nil { return err } } the function BodyCloser.Close() call quic-go->http3->body.go Close() like : ` func (r *body) Close() error { // quic.Stream.Close() closes the write side, not the read side if r.isRequest { return r.str.Close() } r.requestDone() r.str.CancelRead(quic.ErrorCode(errorRequestCanceled)) return nil }

    `

    this call quic-go->stream.go function 👍 func (s *stream) Close() error { if err := s.sendStream.Close(); err != nil { return err } return nil }

    the function s.sendStream.Close() will call func (s *sendStream) Close() error , this function call s.ctxCancel() to cancel context. so the request reverseproxy will be canceled.

    please help me how to fix this bug?

  • support Go 1.15

    support Go 1.15

    As of https://go-review.googlesource.com/c/go/+/234237 last week, tls.ClientSessionState has been modified, so I see panics on the latest version:

    panic: qtls.ClientSessionState not compatible with tls.ClientSessionState
    
    goroutine 1 [running]:
    github.com/lucas-clemente/quic-go/internal/handshake.init.2()
    	/home/mvdan/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/handshake/unsafe.go:26 +0x205
    

    I assume this requires a bit of extra code to handle the go1.15 build tag. beta1 was released recently, and thankfully it includes that commit, so you can add that tagged version to CI to test the fix. RC1 should be out in about two weeks, and I doubt they'll change the tls package further.

  • Connection seems dead for 30s, then closes and starts a new one.

    Connection seems dead for 30s, then closes and starts a new one.

    I have an issue where a QUIC video stream seems dead for about 30 seconds before restarting a new connection (new CHLO etc.), this happens about 8 times in the 10min video.

    Setup:

    • Server: Caddy using QUIC
    • Client: Chromium 58.0.3029.96 with force-quic-on server
    • node in between to limit throughput with tcconfig (using netem/tc) and tcpdump capture

    Might be related to #576 because:

    1. The last packet sent by the server is at 03:31:24.277
    2. everything is congestion limited
    3. The client keeps sending Ack frames (I suppose for earlier video segments)
    4. Everythin seems normal up until (and including) 03:31:35.415
    5. Then no traffic for 20 seconds after which the client sends something strange:
    frames.RstStreamFrame{StreamID:0x7, ErrorCode:0x6, ByteOffset:0x0}
    Ignoring error in session: RST_STREAM received for unknown stream
    
    1. This is ignored, but another 20 seconds later, the client closes the connection: ConnectionCloseFrame{ErrorCode:0x19, ReasonPhrase:"No recent network activity."}\
    2. After this the client starts a new connection an everything is fine for a while.

    I have a Wireshark capture, but it is 140MB because of the video. [edit: removed log as it cluttered the conversation]

  • http3: support WebTransport

    http3: support WebTransport

    This PR adds initial support for the WebTransport draft.

    To see this in action, open these demos in Chrome Canary:

    • Simple demo: https://basic.webtransport.dev/
    • Multiplayer mouse cursor demo: https://cursors.webtransport.dev/

    Background

    Internally, it exposes a bit of additional API from the http3 package, including an http3.Conn which wraps quic.EarlySession and an http3.RequestStream which wraps quic.Stream.

    An http3.Conn allows client and server code to share common stream and frame handling, as well as providing a foundation for (de)multiplexing datagrams in support of the MASQUE datagram draft. An http3.RequestStream is used to read and write HEADERS and DATA frames, as well as process other HTTP/3 frames like MASQUE CAPSULE frames.

    • An http3.ServerConn is constructed using http3.Accept(quic.EarlySession, Settings).
    • An http3.ClientConn is constructed using http3.Open(quic.EarlySession, Settings).
    • A server http3.RequestStream is accepted from (ServerConn).AcceptRequestStream(context.Context).
    • A client http3.RequestStream is opened with (ClientConn).OpenRequestStream(context.Context).

    It is possible to construct alternate HTTP/3 clients or servers using these primitives.

    This PR builds on #3238 and #3254. It fixes #3191, and replaces #3226. It also adds support for HTTP trailers, modeled after the trailers interface in the standard net/http package.

    To do

    • [x] Datagram support
    • [x] Update existing tests
    • [x] Wait for SETTINGS: https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/pull/56
    • [x] Trailers support
    • [x] WebTransport support in http3.RoundTripper
    • [x] Tests for WebTransport features
    • [ ] Integration tests with headless Chromium

    Screenshots

    Chrome demonstrating WebTransport unidirectional, bidirectional streams, and datagrams:

    quic-go-webtransport-datagrams-2
  • WebTransport Support

    WebTransport Support

    Hi, I try to connect http3 server writed by quic-go. And I setup https by tls certification files. When I try to use WebTransport in web:

    let trans = new WebTransport('https://rtc1.live.corp.xxxx.com:443/live/2000.flv');
    

    But it fail and console log is:

    Failed to establish a connection to https://rtc1.live.corp.xxxx.com/live/2000.flv: net::ERR_QUIC_PROTOCOL_ERROR.QUIC_TLS_CERTIFICATE_UNKNOWN (TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown).
    

    but I write http3 client by quicgo and use the http3 client to connect http3 server by quic-go, It work fine.

    My chrome version is 91.0.4472.77.

    Please help.

  • pointers for implementing the client

    pointers for implementing the client

    I'd like to try implementing a client, but I can't tell how much of the session code is going to work or needs to change. It looked almost as if a client API just needs to wrap the rest of the protocol / session code, but I figured I would ask first before digging too deep.

  • Transport Performance in the wild

    Transport Performance in the wild

    I wrote a couple of simple programs to test libp2p transport performance, and specifically compare QUIC to TCP (see https://github.com/vyzo/libp2p-perf-test).

    Running a server in a linode in NJ and a client in a linode in Frankfurt, I have observed the following:

    • QUIC is almost 3x slower than TCP
    • Adding more streams slows down QUIC transfers even further.

    Specifically, I used a 1GiB file with random data, with the timings below.

    Transferring the file 3 times over TCP-vs-QUIC:

    root@li1494-172:~# for x in {1..3}; do ./go/bin/test-client /ip4/50.116.48.114/tcp/4001/p2p/QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR; done
    2020/06/04 18:23:39 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 18:23:39 Connected; requesting data...
    2020/06/04 18:23:39 Transfering data...
    2020/06/04 18:24:09 Received 1073741824 bytes in 30.149238941s
    2020/06/04 18:24:09 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 18:24:10 Connected; requesting data...
    2020/06/04 18:24:10 Transfering data...
    2020/06/04 18:24:47 Received 1073741824 bytes in 37.456968339s
    2020/06/04 18:24:48 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 18:24:48 Connected; requesting data...
    2020/06/04 18:24:48 Transfering data...
    2020/06/04 18:25:17 Received 1073741824 bytes in 29.308343925s
    root@li1494-172:~# for x in {1..3}; do ./go/bin/test-client /ip4/50.116.48.114/udp/4001/quic/p2p/QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR; done
    2020/06/04 18:25:32 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 18:25:32 Connected; requesting data...
    2020/06/04 18:25:32 Transfering data...
    2020/06/04 18:27:17 Received 1073741824 bytes in 1m44.911661928s
    2020/06/04 18:27:18 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 18:27:18 Connected; requesting data...
    2020/06/04 18:27:18 Transfering data...
    2020/06/04 18:28:52 Received 1073741824 bytes in 1m34.259246794s
    2020/06/04 18:28:52 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 18:28:52 Connected; requesting data...
    2020/06/04 18:28:52 Transfering data...
    2020/06/04 18:30:35 Received 1073741824 bytes in 1m42.629025709s
    

    Transferring the file twice using 2 parallel streams:

    root@li1494-172:~# ./go/bin/test-client -streams 2 /ip4/50.116.48.114/tcp/4001/p2p/QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 19:21:54 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 19:21:55 Connected; requesting data...
    2020/06/04 19:21:55 Transferring data in 2 parallel streams
    2020/06/04 19:22:52 Received 2147483648 bytes in 57.743506072s
    root@li1494-172:~# ./go/bin/test-client -streams 2 /ip4/50.116.48.114/udp/4001/quic/p2p/QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 19:23:04 Connecting to QmUgxn8vaVgVDnSxM6qhQzyeXTYXesjJM7iG9TomZjpPcR
    2020/06/04 19:23:05 Connected; requesting data...
    2020/06/04 19:23:05 Transferring data in 2 parallel streams
    2020/06/04 19:26:48 Received 2147483648 bytes in 3m43.026014572s
    

    cc @stebalien

  • race condition in sendWindowSize

    race condition in sendWindowSize

    ==================
    WARNING: DATA RACE
    Read at 0x00c0001d0000 by goroutine 25:
      github.com/lucas-clemente/quic-go/internal/flowcontrol.(*baseFlowController).sendWindowSize()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/flowcontrol/base_flow_controller.go:60 +0x51
      github.com/lucas-clemente/quic-go/internal/flowcontrol.(*connectionFlowController).SendWindowSize()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/flowcontrol/connection_flow_controller.go:42 +0x4d
      github.com/lucas-clemente/quic-go/internal/flowcontrol.(*streamFlowController).SendWindowSize()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/flowcontrol/stream_flow_controller.go:110 +0x96
      github.com/lucas-clemente/quic-go.(*sendStream).Write()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/send_stream.go:98 +0x588
      github.com/lucas-clemente/quic-go.(*stream).Write()
          <autogenerated>:1 +0xcf
      NGN/common/sm-quic-conn.(*Conn).Write()
          /home/go/src/NGN/common/sm-quic-conn/conn.go:311 +0x101
      NGN/common/sm-conn.SendSMHeader()
          /home/go/src/NGN/common/sm-conn/sm-conn.go:165 +0x55a
      NGN/common/sm-conn.SMhandshake()
          /home/go/src/NGN/common/sm-conn/sm-conn.go:224 +0x1a1
      main.forwardConnection()
          /home/go/src/NGN/cmd/client/client.go:319 +0xbd2
    
    Previous write at 0x00c0001d0000 by goroutine 15:
      github.com/lucas-clemente/quic-go/internal/flowcontrol.(*baseFlowController).AddBytesSent()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/flowcontrol/base_flow_controller.go:46 +0x79
      github.com/lucas-clemente/quic-go/internal/flowcontrol.(*connectionFlowController).AddBytesSent()
          <autogenerated>:1 +0x61
      github.com/lucas-clemente/quic-go/internal/flowcontrol.(*streamFlowController).AddBytesSent()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/flowcontrol/stream_flow_controller.go:106 +0xa6
      github.com/lucas-clemente/quic-go.(*sendStream).getDataForWriting()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/send_stream.go:232 +0x55e
      github.com/lucas-clemente/quic-go.(*sendStream).popStreamFrameImpl()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/send_stream.go:178 +0x366
      github.com/lucas-clemente/quic-go.(*sendStream).popStreamFrame()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/send_stream.go:155 +0xa9                                                                     
      github.com/lucas-clemente/quic-go.(*stream).popStreamFrame()                                                                                                   
          <autogenerated>:1 +0x86
      github.com/lucas-clemente/quic-go.(*framerI).AppendStreamFrames()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/framer.go:95 +0x44d
      github.com/lucas-clemente/quic-go.(*packetPacker).composeNextPacket()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/packet_packer.go:349 +0x5b3
      github.com/lucas-clemente/quic-go.(*packetPacker).PackPacket()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/packet_packer.go:264 +0x3cd
      github.com/lucas-clemente/quic-go.(*session).sendPacket()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/session.go:1105 +0x22b
      github.com/lucas-clemente/quic-go.(*session).sendPackets()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/session.go:1013 +0x6f4
      github.com/lucas-clemente/quic-go.(*session).run()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/session.go:426 +0x1688
      github.com/lucas-clemente/quic-go.(*client).establishSecureConnection.func1()
          /home/go/go/pkg/mod/github.com/lucas-clemente/[email protected]/client.go:269 +0x85
    
    Goroutine 25 (running) created at:
      main.XXX()
          XXX/client.go:250 +0x79f
      main.clientMain()
          XXX/client.go:168 +0x6a8
      main.(*program).Run()
          XXX/client.go:569 +0x139
    
  • only include quic-trace when the quictrace build flag is set

    only include quic-trace when the quictrace build flag is set

    Fixes #2797.

    I'm not ready to drop quic-trace yet, but it turns out to be really easy to hide behind a build tag.

    With quic-trace:

     ❯ go build -tags quictrace -o server example/main.go &&  go build -tags quictrace -o client ./example/client/main.go && du -sh client server
     14M	client
     15M	server
    

    Without quic-trace:

    ❯ go build -o server example/main.go &&  go build -o client ./example/client/main.go && du -sh client server
    8.8M	client
     13M	server
    

    Not sure why the difference is so much bigger for the client. @egonelbre any ideas?

  • PMTUD may be implemented incorrectly

    PMTUD may be implemented incorrectly

    Hi,

    We talked about the DF bit on Windows a while ago, and I submitted https://github.com/lucas-clemente/quic-go/pull/3155. But apparently it led to this unforeseen problem https://github.com/lucas-clemente/quic-go/issues/3273 so PMTUD ended up being disabled on Windows as a dirty fix. As I revisited this today I realized that perhaps there is something fundamentally wrong with the way quic-go currently implements PMTUD, and it's not really a Windows issue.

    Previously we both assumed that the DF bit is enabled by default on Linux. But that's not true, as the man page says this:

    image

    The default behavior on Linux (IP_PMTUDISC_WANT) is to only set DF bit when the packet is smaller than the path MTU, and fragment the packet otherwise. This implies that right now even if quic-go sends a packet larger than the path MTU, it will still be fragmented, sent, and received, nullifying PMTUD altogether. And if you explicitly set it to IP_PMTUDISC_DO, you will get a similar behavior as on Windows - errors when trying to send packets larger than the path MTU, instead of discarding them silently.

    I wrote a demo and verified this on my Ubuntu 20.04 server, which has an MTU of 1500. When it sends packets smaller than 1500, the DF bit is set. When it sends packets larger than 1500, it fragments them and sends them successfully nonetheless.

    image

  • Question about setting IP_PKTINFO for QUIC servers listening on wildcard (0.0.0.0).

    Question about setting IP_PKTINFO for QUIC servers listening on wildcard (0.0.0.0).

    Hey guys.

    I'm trying to solve the problem raised in https://github.com/lucas-clemente/quic-go/issues/1736 by setting IP_PKTINFO on as sockopt but this doesn't seem to work.

    How can I tell:

    To reproduce this, I have a server behind anycast with a bunch of ips on a single NIC.

    This is the server: https://pastebin.com/wJuVcWya (its the hello world example repurposed a bit).

    My expectation here when I run tcpdump is I should see communication flow the from the same ip both ways but this isn't the case.

    sudo tcpdump -n -i eth0 port 4242 and udp
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on vlan100, link-type EN10MB (Ethernet), capture size 262144 bytes
    14:44:27.742629 IP 17.24.60.44.50152 > 19.41.20.20.4242: UDP, length 1252
    14:44:27.743298 IP 17.24.60.13.4242 > 17.24.60.44.50152: UDP, length 37
    

    When running my server with strace I also cannot see ipi_addr on sendmsg().

    I'm using the latest revision of quic-go and running go1.17.

  • Throughput of quic-go

    Throughput of quic-go

    Hi community,

    I am testing the maximum achievable throughput of quic-go and for this purpose I've modified the echo.go example to read a large file (>15GB) and send it to a server. The client and server are running on two different hosts (Ubuntu 22) with a unused 10Gigabit link between them. I am achieving a maximum throughput of ca. 1100 Mbit/s. Would be this number expect by anyone else or should quic-go actually be able to achieve more? I'm open to feedback to improve my example so that we can see a better throughput. Thanks in advance.

  • flaky 0-RTT integration test

    flaky 0-RTT integration test

    ------------------------------
    0-RTT with QUIC version draft-29
      waits for a connection until the handshake is done
      /home/circleci/project/integrationtests/self/zero_rtt_test.go:243
    Sent 4 0-RTT packets.------------------------------
    • [FAILED] [0.199 seconds]
    0-RTT
    /home/circleci/project/integrationtests/self/zero_rtt_test.go:25
      with QUIC version draft-29
      /home/circleci/project/integrationtests/self/zero_rtt_test.go:31
        [It] waits for a connection until the handshake is done
        /home/circleci/project/integrationtests/self/zero_rtt_test.go:243
    
      Begin Captured GinkgoWriter Output >>
        Sent 4 0-RTT packets.
      << End Captured GinkgoWriter Output
    
      Expected
          <uint32>: 4
      To satisfy at least one of these matchers: [%!s(*matchers.BeEquivalentToMatcher=&{2}) %!s(*matchers.BeEquivalentToMatcher=&{3})]
      In [It] at: /home/circleci/project/integrationtests/self/zero_rtt_test.go:311
    
      Full Stack Trace
        github.com/lucas-clemente/quic-go/integrationtests/self_test.glob..func27.1.7()
        	/home/circleci/project/integrationtests/self/zero_rtt_test.go:311 +0x181a
  • flaky send queue test

    flaky send queue test

    ------------------------------
    • [FAILED] [0.001 seconds]
    Send Queue
    /home/parallels/src/go/src/github.com/lucas-clemente/quic-go/send_queue_test.go:11
      [It] signals when sending is possible again, when the first write succeeded
      /home/parallels/src/go/src/github.com/lucas-clemente/quic-go/send_queue_test.go:76
    
      Expected
          <bool>: true
      to be false
      In [It] at: /home/parallels/src/go/src/github.com/lucas-clemente/quic-go/send_queue_test.go:100
    ------------------------------
    SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
    
    
    Summarizing 1 Failure:
      [FAIL] Send Queue [It] signals when sending is possible again, when the first write succeeded
      /home/parallels/src/go/src/github.com/lucas-clemente/quic-go/send_queue_test.go:100
    
  • reduce the size of messageChan channel in the crypto setup

    reduce the size of messageChan channel in the crypto setup

    Part of #3663.

    name          old time/op    new time/op    delta
    Handshake-10     732µs ± 3%     722µs ± 1%  -1.26%  (p=0.012 n=16+17)
    
    name          old alloc/op   new alloc/op   delta
    Handshake-10     217kB ± 0%     212kB ± 0%  -2.39%  (p=0.000 n=20+15)
    
    name          old allocs/op  new allocs/op  delta
    Handshake-10     3.03k ± 0%     3.03k ± 0%  +0.02%  (p=0.023 n=16+16)
    
quiwi 🥝 - QUIC implementation in Go.

Quiwi ?? QUIC transport protocol (https://quicwg.org/) implementation in Go. The goal is to provide low level APIs for applications or protocols using

Nov 16, 2022
WebTransport implementation based on quic-go (https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/)

webtransport-go webtransport-go is an implementation of the WebTransport protocol, based on quic-go. It currently implements draft-02 of the specifica

Dec 31, 2022
Antenna RPC is an RPC protocol for distributed computing, it's based on QUIC and Colfer. its currently an WIP.

aRPC - Antenna Remote Procedure Call Antenna remote procedure call (aRPC) is an RPC protocol focused on distributed processing and HPC. aRPC is implem

Jun 16, 2021
WebTransport-Go - WebTransport Server based on quic-go

WebTransportServer 基于quic-go的封装,用于支持WebTransport。以下是使用Example import ( "fmt"

Dec 13, 2022
Pure Go implementation of the WebRTC API
Pure Go implementation of the WebRTC API

Pion WebRTC A pure Go implementation of the WebRTC API New Release Pion WebRTC v3.0.0 has been released! See the release notes to learn about new feat

Jan 1, 2023
A Windows named pipe implementation written in pure Go.

npipe Package npipe provides a pure Go wrapper around Windows named pipes. Windows named pipe documentation: http://msdn.microsoft.com/en-us/library/w

Jan 1, 2023
Pure Go implementation of the WebRTC API
Pure Go implementation of the WebRTC API

Pure Go implementation of the WebRTC API

Jan 8, 2023
🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go./ gnet 是一个高性能、轻量级、非阻塞的事件驱动 Go 网络框架。
🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go./ gnet 是一个高性能、轻量级、非阻塞的事件驱动 Go 网络框架。

English | ???? 中文 ?? Introduction gnet is an event-driven networking framework that is fast and lightweight. It makes direct epoll and kqueue syscalls

Jan 2, 2023
Pure-Go library for cross-platform local peer discovery using UDP multicast :woman: :repeat: :woman:
Pure-Go library for cross-platform local peer discovery using UDP multicast :woman: :repeat: :woman:

peerdiscovery Pure-go library for cross-platform thread-safe local peer discovery using UDP multicast. I needed to use peer discovery for croc and eve

Jan 8, 2023
Distributed RTC System by pure Go and Flutter
Distributed RTC System by pure Go and Flutter

ION is a distributed real-time communication system, the goal is to chat anydevice, anytime, anywhere! Distributed Real-time Communication System ION

Jan 2, 2023
A pure Unix shell script implementing ACME client protocol

An ACME Shell script: acme.sh An ACME protocol client written purely in Shell (Unix shell) language. Full ACME protocol implementation. Support ACME v

Jan 2, 2023
Pure-Go HBase client

Golang HBase client This is a pure Go client for HBase. Current status: beta. Supported Versions HBase >= 1.0 Installation go get github.com/tsuna/goh

Jan 3, 2023
Pure Go Brotli encoder and decoder

This package is a brotli compressor and decompressor implemented in Go. It was translated from the reference implementation (https://github.com/google

Dec 28, 2022
Snugger is a light weight but fast network recon scanner that is written from pure golang
Snugger is a light weight but fast network recon scanner that is written from pure golang

Snugger is a light weight but fast network recon scanner that is written from pure golang. with this scann you can ARP your network, port scan hosts and host lists, as well as scan for BSSId

May 19, 2022
A go implementation of the STUN client (RFC 3489 and RFC 5389)

go-stun go-stun is a STUN (RFC 3489, 5389) client implementation in golang (a.k.a. UDP hole punching). RFC 3489: STUN - Simple Traversal of User Datag

Jan 5, 2023
Fast RFC 5389 STUN implementation in go

STUN Package stun implements Session Traversal Utilities for NAT (STUN) [RFC5389] protocol and client with no external dependencies and zero allocatio

Nov 28, 2022
A LWM2M Client and Server implementation (For Go/Golang)

Betwixt - A LWM2M Client and Server in Go Betwixt is a Lightweight M2M implementation written in Go OMA Lightweight M2M is a protocol from the Open Mo

Dec 23, 2022
A Socket.IO backend implementation written in Go

go-socket.io The socketio package is a simple abstraction layer for different web browser- supported transport mechanisms. It is fully compatible with

Sep 25, 2022
An Etsy StatsD (https://github.com/etsy/statsd) implementation in Go

STATSD-GO Port of Etsy's statsd, written in Go. This was forked from https://github.com/amir/gographite to provide Ganglia submission support. USAGE U

Mar 5, 2021