17 个版本 (7 个重大更新)

0.7.1 2024 年 7 月 21 日
0.6.0 2024 年 5 月 4 日
0.4.0 2024 年 3 月 24 日

#7 in #tls-server

Download history 6/week @ 2024-04-17 162/week @ 2024-05-01 5/week @ 2024-05-08 2/week @ 2024-05-15 5/week @ 2024-05-22 1/week @ 2024-06-05 2/week @ 2024-06-12 18/week @ 2024-07-03 229/week @ 2024-07-17 103/week @ 2024-07-24 35/week @ 2024-07-31

每月 <367 次下载
用于 petrel

MIT 许可证

160KB
4K SLoC

Diameter

直径协议的 Rust 实现。

Crates.io MIT licensed Build Status

概述

此库提供了直径协议的 Rust 实现,该协议由 RFC 6733 定义。

入门

安装

将以下内容添加到您的 Rust 项目中的 Cargo.toml

[dependencies]
diameter-rs = "^0.7"

使用方法

直径客户端示例

以下是一个创建直径客户端并发送 Credit-Control-Request (CCR) 消息到服务器并等待响应的示例。

use diameter::avp::flags::M;
use diameter::avp::Enumerated;
use diameter::avp::Identity;
use diameter::avp::UTF8String;
use diameter::avp::Unsigned32;
use diameter::dictionary::{self, Dictionary};
use diameter::flags;
use diameter::transport::DiameterClient;
use diameter::transport::DiameterClientConfig;
use diameter::{ApplicationId, CommandCode, DiameterMessage};
use std::sync::Arc;

#[tokio::main]
async fn main() {
    // Diameter Dictionary
    let dict = Dictionary::new(&[&dictionary::DEFAULT_DICT_XML]);
    let dict = Arc::new(dict);

    // Initialize a Diameter client and connect it to the server
    let client_config = DiameterClientConfig {
        use_tls: false,
        verify_cert: false,
    };
    let mut client = DiameterClient::new("localhost:3868", client_config);
    let mut handler = client.connect().await.unwrap();
    let dict_ref = Arc::clone(&dict);
    tokio::spawn(async move {
        DiameterClient::handle(&mut handler, dict_ref).await;
    });

    // Create a Credit-Control-Request (CCR) Diameter message
    let mut ccr = DiameterMessage::new(
        CommandCode::CreditControl,
        ApplicationId::CreditControl,
        flags::REQUEST,
        1123158611,
        3102381851,
        dict,
    );
    ccr.add_avp(264, None, M, Identity::new("host.example.com").into());
    ccr.add_avp(296, None, M, Identity::new("realm.example.com").into());
    ccr.add_avp(263, None, M, UTF8String::new("ses;12345888").into());
    ccr.add_avp(416, None, M, Enumerated::new(1).into());
    ccr.add_avp(415, None, M, Unsigned32::new(1000).into());

    // Send the CCR message to the server and wait for a response
    let response = client.send_message(ccr).await.unwrap();
    let cca = response.await.unwrap();
    println!("Received response: {}", cca);
}

直径服务器示例

以下是一个设置直径服务器以监听传入请求的示例

use diameter::avp::flags::M;
use diameter::avp::Enumerated;
use diameter::avp::Identity;
use diameter::avp::UTF8String;
use diameter::avp::Unsigned32;
use diameter::dictionary::{self, Dictionary};
use diameter::flags;
use diameter::transport::DiameterServer;
use diameter::transport::DiameterServerConfig;
use diameter::DiameterMessage;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    // Diameter Dictionary
    let dict = Dictionary::new(&[&dictionary::DEFAULT_DICT_XML]);
    let dict = Arc::new(dict);

    // Set up a Diameter server listening on a specific port
    let mut server = DiameterServer::new("0.0.0.0:3868", DiameterServerConfig { native_tls: None })
        .await
        .unwrap();

    // Asynchronously handle incoming requests to the server
    let dict_ref = Arc::clone(&dict);
    server
        .listen(
            move |req| {
                let dict_ref2 = Arc::clone(&dict);
                async move {
                    println!("Received request: {}", req);

                    // Create a response message based on the received request
                    let mut res = DiameterMessage::new(
                        req.get_command_code(),
                        req.get_application_id(),
                        req.get_flags() ^ flags::REQUEST,
                        req.get_hop_by_hop_id(),
                        req.get_end_to_end_id(),
                        dict_ref2,
                    );

                    // Add various Attribute-Value Pairs (AVPs) to the response
                    res.add_avp(264, None, M, Identity::new("host.example.com").into());
                    res.add_avp(296, None, M, Identity::new("realm.example.com").into());
                    res.add_avp(263, None, M, UTF8String::new("ses;123458890").into());
                    res.add_avp(416, None, M, Enumerated::new(1).into());
                    res.add_avp(415, None, M, Unsigned32::new(1000).into());
                    res.add_avp(268, None, M, Unsigned32::new(2001).into());

                    // Return the response
                    Ok(res)
                }
            },
            dict_ref,
        )
        .await
        .unwrap();
}

TLS

以下是如何为服务器和客户端设置 TLS 的示例。

具有 TLS 的服务器配置

    let mut cert_file = File::open("server.crt").unwrap();
    let mut certs = vec![];
    cert_file.read_to_end(&mut certs).unwrap();

    let mut key_file = File::open("server.key").unwrap();
    let mut key = vec![];
    key_file.read_to_end(&mut key).unwrap();

    let pkcs8 = native_tls::Identity::from_pkcs8(&certs, &key).unwrap();
    let config = DiameterServerConfig {
        native_tls: Some(pkcs8),
    };

具有 TLS 的客户端配置

    let client_config = DiameterClientConfig {
        use_tls: true,
        verify_cert: false,
    };

依赖项

~4–15MB
~187K SLoC