GitHub - bkchr/picoquic-rs: Picoquic bindings for rust. (original) (raw)

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:

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

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