Skip to main content

ferripfs_config/
routing.rs

1// Ported from: kubo/config/routing.go
2// Kubo version: v0.39.0
3// Original: https://github.com/ipfs/kubo/blob/v0.39.0/config/routing.go
4//
5// Original work: Copyright (c) Protocol Labs, Inc.
6// Port: Copyright (c) 2026 ferripfs contributors
7// SPDX-License-Identifier: MIT OR Apache-2.0
8
9//! Routing configuration for DHT and delegated routing.
10
11use crate::{Flag, OptionalString};
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14
15/// Default routing type
16pub const DEFAULT_ROUTING_TYPE: &str = "auto";
17
18/// Routing configuration section
19#[derive(Debug, Clone, Default, Serialize, Deserialize)]
20#[serde(rename_all = "PascalCase")]
21pub struct Routing {
22    /// Routing type: "auto", "autoclient", "dht", "dhtclient", "dhtserver", "none", "custom"
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub r#type: Option<OptionalString>,
25
26    /// Enable accelerated DHT client
27    #[serde(
28        default,
29        skip_serializing_if = "Option::is_none",
30        rename = "AcceleratedDHTClient"
31    )]
32    pub accelerated_dht_client: Option<Flag>,
33
34    /// Allow loopback addresses on LAN DHT
35    #[serde(
36        default,
37        skip_serializing_if = "Option::is_none",
38        rename = "LoopbackAddressesOnLanDHT"
39    )]
40    pub loopback_addresses_on_lan_dht: Option<Flag>,
41
42    /// Provider peer IDs to ignore
43    #[serde(default)]
44    pub ignore_providers: Vec<String>,
45
46    /// Delegated router URLs
47    #[serde(default)]
48    pub delegated_routers: Vec<String>,
49
50    /// Custom routers configuration
51    #[serde(default, skip_serializing_if = "Option::is_none")]
52    pub routers: Option<HashMap<String, RouterConfig>>,
53
54    /// Method routing configuration
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub methods: Option<HashMap<String, MethodConfig>>,
57}
58
59/// Router configuration
60#[derive(Debug, Clone, Serialize, Deserialize)]
61#[serde(rename_all = "PascalCase")]
62pub struct RouterConfig {
63    /// Router type: "http", "dht", "sequential", "parallel"
64    pub r#type: RouterType,
65
66    /// Router-specific parameters
67    pub parameters: serde_json::Value,
68}
69
70/// Router types
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
72#[serde(rename_all = "lowercase")]
73pub enum RouterType {
74    Http,
75    Dht,
76    Sequential,
77    Parallel,
78}
79
80/// DHT mode
81#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
82#[serde(rename_all = "lowercase")]
83pub enum DhtMode {
84    Server,
85    Client,
86    #[default]
87    Auto,
88}
89
90/// Method routing configuration
91#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(rename_all = "PascalCase")]
93pub struct MethodConfig {
94    /// Router name to use for this method
95    pub router_name: String,
96}
97
98/// HTTP router parameters
99#[derive(Debug, Clone, Default, Serialize, Deserialize)]
100#[serde(rename_all = "PascalCase")]
101pub struct HttpRouterParams {
102    /// Endpoint URL
103    pub endpoint: String,
104
105    /// Maximum batch size for provide operations
106    #[serde(default)]
107    pub max_provide_batch_size: i32,
108
109    /// Maximum concurrency for provide operations
110    #[serde(default)]
111    pub max_provide_concurrency: i32,
112}
113
114/// DHT router parameters
115#[derive(Debug, Clone, Default, Serialize, Deserialize)]
116#[serde(rename_all = "PascalCase")]
117pub struct DhtRouterParams {
118    /// DHT mode
119    pub mode: DhtMode,
120
121    /// Enable accelerated DHT client
122    #[serde(
123        default,
124        skip_serializing_if = "Option::is_none",
125        rename = "AcceleratedDHTClient"
126    )]
127    pub accelerated_dht_client: Option<bool>,
128
129    /// Use public IP network
130    #[serde(default, rename = "PublicIPNetwork")]
131    pub public_ip_network: bool,
132}
133
134impl Routing {
135    /// Get the routing type with default
136    pub fn routing_type(&self) -> &str {
137        self.r#type
138            .as_ref()
139            .and_then(|t| t.as_str())
140            .unwrap_or(DEFAULT_ROUTING_TYPE)
141    }
142}
143
144#[cfg(test)]
145mod tests {
146    use super::*;
147
148    #[test]
149    fn test_routing_default() {
150        let routing = Routing::default();
151        assert_eq!(routing.routing_type(), "auto");
152    }
153
154    #[test]
155    fn test_router_type_serialization() {
156        let json = serde_json::to_string(&RouterType::Http).unwrap();
157        assert_eq!(json, "\"http\"");
158    }
159
160    #[test]
161    fn test_dht_mode_serialization() {
162        let json = serde_json::to_string(&DhtMode::Server).unwrap();
163        assert_eq!(json, "\"server\"");
164    }
165}