3个不稳定版本

0.2.0 2021年10月14日
0.1.2 2020年12月14日
0.1.1 2020年12月7日

#312异步

Download history 97/week @ 2024-04-22 80/week @ 2024-04-29 85/week @ 2024-05-06 79/week @ 2024-05-13 83/week @ 2024-05-20 88/week @ 2024-05-27 90/week @ 2024-06-03 60/week @ 2024-06-10 74/week @ 2024-06-17 70/week @ 2024-06-24 24/week @ 2024-07-01 44/week @ 2024-07-08 100/week @ 2024-07-15 75/week @ 2024-07-22 58/week @ 2024-07-29 89/week @ 2024-08-05

327 每月下载量
用于 13 个crate(4个直接使用)

自定义许可证

105KB
2.5K SLoC

Build Status codecov

kuska handshake

kuska在Runasimi中意为“一起”

kuska是用Rust编写的去中心化社交网络Secure Scuttlebut的实现,它不旨在提供用户界面和某些客户端(如PatchworkPatchbay)中实现的功能,而是提供用于开发Secure Scuttlebut网络应用程序的完整库集。

kuska-handshake是SSB中使用的握手和box stream的实现,有关该协议的详细信息,请参阅https://ssbc.github.io/scuttlebutt-protocol-guide/

当前实现包含

  • 使用sodiumoxide实现的协议的无差别实现
  • 同步版本(需要sync功能)
  • 异步async_std版本(需要async_std功能,并提供对tokio的包装,需要tokio_compat功能)

同步客户端/服务器

服务器

创建服务器密钥对

let (pk, sk) = ed25519::gen_keypair();
let pk_b64 = base64::encode_config(&pk, base64::STANDARD);

定义要连接的网络

let net_id_hex = "d4a1cb88a66f02f8db635ce26441cc5dac1b08420ceaac230839b755845a9ffb";
let net_id = auth::Key::from_slice(&hex::decode(net_id_hex).unwrap()).unwrap();

监听,接受套接字并执行握手

let listener = TcpListener::bind(...).unwrap();
let (socket, addr) = listener.accept().unwrap();
let handshake = handshake_server(&socket, net_id, pk, sk)?;

握手执行后,创建两个box stream,一个用于发送数据,另一个用于接收数据,这些box stream实现了std::io::Readstd::io::Write,以在它们上执行常规I/O操作。

let (key_nonce_send, key_nonce_recv) = KeyNonce::from_handshake(handshake);
let (mut box_stream_read, mut box_stream_write) =
        BoxStream::new(&socket, &socket, key_nonce_send, key_nonce_recv).split_read_write();

box_stream_read.read_exact(...)
box_stream_write.write_all(...)

客户端

创建客户端密钥对

let (pk, sk) = ed25519::gen_keypair();
let pk_b64 = base64::encode_config(&pk, base64::STANDARD);

连接到服务器,执行握手(您需要服务器公钥),并创建用于通信的流盒子

let socket = TcpStream::connect(...).unwrap();
let handshake = handshake_client(&socket, net_id, pk, sk, server_pk)?;

let (key_nonce_send, key_nonce_recv) = KeyNonce::from_handshake(handshake);
let (mut box_stream_read, mut box_stream_write) =
  BoxStream::new(&socket, &socket, key_nonce_send, key_nonce_recv).split_read_write();

box_stream_read.read_exact(...)
box_stream_write.write_all(...)

async_std 客户端

async_std 客户端类似于 sync 版本,只是所有函数都是异步的,并使用 async_std::io::Readasync_std::io::Write 用于流盒子

use async_std::io::{Read,Write};
use async_std::net::TcpStream;
use kuska_handshake::async_std::{handshake_client,BoxStream};

#[async_std::main]
async fn main() -> Result<T, Box<dyn Error>> {
  ...
  let mut socket = TcpStream::connect("127.0.0.1:8008").await?;
  let (_,handshake) = handshake_client(&mut socket, ssb_net_id(), pk, sk, server_pk).await?;

  let (box_stream_read, box_stream_write) =
      BoxStream::from_handhake(&socket, &socket, handshake, 0x8000)
      .split_read_write();

tokio 客户端

要使用 tokio,您需要使用 kuska_handshake::async_std::tokio_compat 中使用的包装器

use tokio::net::TcpStream;
use kuska_handshake::async_std::{BoxStream,handshake_client,TokioCompatExt,TokioCompatExtRead,TokioCompatExtWrite};

let tokio_socket : TcpStream = TcpStream::connect("127.0.0.1:8008").await?;
let asyncstd_socket = TokioCompatExt::wrap(tokio_socket);

let (asyncstd_socket,handshake) = handshake_client(asyncstd_socket, ssb_net_id(), pk, sk.clone(), pk).await?;
let mut tokio_socket = asyncstd_socket.into_inner();
let (read,write) = tokio_socket.split();

let read = TokioCompatExtRead::wrap(read);
let write = TokioCompatExtWrite::wrap(write);

let (box_stream_read, box_stream_write) =
    BoxStream::from_handhake(read, write, handshake, 0x8000)
    .split_read_write();

依赖项

~17–26MB
~152K SLoC