bkchr / picoquic-rs

Picoquic bindings for rust.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Picoquic-rs - Tokio aware bindings of picoquic

Build Status

Picoquic is a minimalist implementation of the QUIC protocol by the IETF. The protocol is still in development and so the implementation.

Building

For building picoquic-rs, you need the following dependencies:

  • clang
  • openssl Building is currently only tested on Linux. Clone the repo and fetch the submodules:
git submodule init
git submodule update

To build the project, run cargo build. picoquic-sys will also build the picoquic c-library for you (hopefully).

Example

Client

extern crate bytes;
extern crate futures;
extern crate picoquic;
extern crate tokio;

use picoquic::{Config, Context};

use bytes::Bytes;

use futures::{Future, Sink, Stream};

fn main() {
    let mut evt_loop = tokio::runtime::Runtime::new().unwrap();

    let manifest_dir = env!("CARGO_MANIFEST_DIR");

    let mut config = Config::new();
    config.set_root_certificate_filename(format!("{}/examples/ca_cert.pem", manifest_dir));

    let mut client = Context::new(&([0, 0, 0, 0], 0).into(), evt_loop.executor(), config).unwrap();

    let mut con = evt_loop
        .block_on(client.new_connection(([127, 0, 0, 1], 22222).into(), "server.test"))
        .unwrap();

    let stream = evt_loop.block_on(con.new_bidirectional_stream()).unwrap();

    let stream = evt_loop
        .block_on(stream.send(Bytes::from("hello server")))
        .unwrap();

    let answer = evt_loop
        .block_on(
            stream
                .into_future()
                .map(|(m, _)| m.unwrap())
                .map_err(|(e, _)| e),
        )
        .unwrap();

    println!("Got: {:?}", answer);
}

Server

extern crate bytes;
extern crate futures;
extern crate picoquic;
extern crate tokio;

use picoquic::{Config, Context};

use futures::{Future, Sink, Stream};

use bytes::Bytes;

fn main() {
    let evt_loop = tokio::runtime::Runtime::new().unwrap();

    let manifest_dir = env!("CARGO_MANIFEST_DIR");

    let mut config = Config::new();
    config.set_certificate_chain_filename(format!("{}/examples/cert.pem", manifest_dir));
    config.set_private_key_filename(format!("{}/examples/key.pem", manifest_dir));

    let server = Context::new(&([0, 0, 0, 0], 22222).into(), evt_loop.executor(), config).unwrap();

    println!("Server listening on: {}", server.local_addr());

    evt_loop.block_on_all(
        server
            .for_each(|c| {
                println!("New connection from: {}", c.peer_addr());

                tokio::spawn(
                    c.for_each(move |s| {
                        // We print the received message and sent a new one, after that we collect all
                        // remaining messages. The collect is a "hack" that prevents that the `Stream` is
                        // dropped too early.
                        tokio::spawn(
                            s.into_future()
                                .map_err(|_| ())
                                .and_then(|(m, s)| {
                                    println!("Got: {:?}", m);
                                    s.send(Bytes::from("hello client")).map_err(|_| ())
                                })
                                .and_then(|s| s.collect().map_err(|_| ()))
                                .map(|_| ()),
                        );
                        Ok(())
                    })
                    .map_err(|_| ()),
                );

                Ok(())
            })
    ).unwrap();
}

Todo

  • My first crate/project that uses failure and I'm not happy with the current error structure :(
  • Support more configuration options
  • I currently don't check all return codes of the c functions.
  • Remove the TODOs from the source code

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

License: MIT/Apache-2.0

About

Picoquic bindings for rust.


Languages

Language:Rust 99.9%Language:Dockerfile 0.1%