oxy_upnp_igd/lib.rs
1/* This file is part of oxy-upnp-igd
2 *
3 * Copyright (C) 2026 Gioacchino Mazzurco <gio@polymathes.cc>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19//! # oxy-upnp-igd
20//!
21//! Minimal UPnP Internet Gateway Device (IGD) port mapping library.
22//!
23//! ## Features
24//! - UPnP gateway discovery via SSDP (discovers ALL available gateways)
25//! - Port mapping (Add/Delete) for TCP and UDP
26//! - Automatic port mapping renewal
27//! - External IP address retrieval
28//! - Smol runtime compatible
29//! - Minimal dependencies
30//!
31//! ## Supported Protocols
32//! - TCP
33//! - UDP
34//!
35//! ## Quick Start
36//!
37//! ### Discover Gateways and Get External IP
38//!
39//! ```rust,no_run
40//! use oxy_upnp_igd::discover_gateways;
41//! use std::time::Duration;
42//!
43//! fn main() -> Result<(), Box<dyn std::error::Error>> {
44//! smol::block_on(async {
45//! // Discover all UPnP gateways on the network
46//! let gateways = discover_gateways(Duration::from_secs(3)).await?;
47//!
48//! // Use the first available gateway
49//! if let Some(gateway) = gateways.first() {
50//! let external_ip = gateway.get_external_ip().await?;
51//! println!("External IP: {}", external_ip);
52//! }
53//!
54//! Ok::<(), Box<dyn std::error::Error>>(())
55//! })
56//! }
57//! ```
58//!
59//! ### Add Port Mapping with Automatic Renewal
60//!
61//! ```rust,no_run
62//! use oxy_upnp_igd::{discover_gateways, Protocol};
63//! use smol::Executor;
64//! use std::sync::Arc;
65//! use std::time::Duration;
66//!
67//! fn main() -> Result<(), Box<dyn std::error::Error>> {
68//! smol::block_on(async {
69//! let ex = Arc::new(Executor::new());
70//! let gateways = discover_gateways(Duration::from_secs(3)).await?;
71//! let gateway = &gateways[0];
72//!
73//! // Add port mapping with auto-renewal
74//! let handle = gateway.add_port_mapping_with_renewal(
75//! ex.clone(),
76//! 8080, // internal port
77//! 8080, // external port
78//! "192.168.1.100".parse()?,
79//! Protocol::TCP,
80//! "My App",
81//! 3600, // lease duration (seconds)
82//! Duration::from_secs(3),
83//! ).await?;
84//!
85//! println!("Port mapping active and will auto-renew");
86//! // Mapping stays active until `handle` is dropped
87//!
88//! Ok::<(), Box<dyn std::error::Error>>(())
89//! })
90//! }
91//! ```
92
93pub mod client;
94pub mod error;
95pub mod gateway;
96pub mod http;
97pub mod renewal;
98pub mod ssdp;
99
100pub use client::{
101 add_port_mapping_lazy, discover_gateways, get_local_ipv4_for_gateway, is_port_conflict_error,
102 Protocol, DEFAULT_DISCOVERY_TIMEOUT, DEFAULT_LEASE_DURATION,
103};
104pub use error::{Error, Result};
105pub use gateway::{Gateway, PortMappingEntry};
106pub use renewal::{RenewalConfig, RenewalHandle};