#bindings #don-t #byte #future #c-library #protocols #picoquic

sys picoquic-sys

Provides bindings to the picoquic c-library. Please don’t use this crate directly. Use the picoquic crate.

1 unstable release

Uses old Rust 2015

0.1.0 Feb 2, 2018

#99 in #don-t


Used in picoquic

MIT/Apache

4MB
72K SLoC

Bitbake 37K SLoC // 0.0% comments C 29K SLoC // 0.1% comments GNU Style Assembly 2.5K SLoC // 0.0% comments Python 1.5K SLoC // 0.2% comments Visual Studio Project 1.5K SLoC C++ 272 SLoC // 0.1% comments Visual Studio Solution 162 SLoC Arduino C++ 67 SLoC // 0.1% comments Rust 47 SLoC // 0.0% comments Perl 33 SLoC Forge Config 12 SLoC

Contains (Zip file, 17MB) src/picoquic/Report20171222-1702.vspx

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

Dependencies