Bump version to 0.1.1 and enhance IP detection with timeout support

Bump version to 0.1.1 and enhance IP detection with timeout support

- Update version in Cargo.toml and Cargo.lock to 0.1.1
- Update .DEFAULT_GOAL in Makefile to 'release'
- Update Makefile to synchronize version in README.md
- Change default DNS port from 80 to 53 in IP detection
- Add `guess_local_ip_with_timeout` function with configurable timeout
- Add `list_all_ips` function to list all non-loopback IP addresses
- Add `find_process_using_port` function to identify processes using specific ports
- Reorder parameters in `find_process_using_port` for better API design
- Update documentation and examples in README.md and lib.rs
- Add version.txt file to track current version
- Minor code improvements and test updates
This commit is contained in:
2026-02-28 18:26:17 +01:00
parent dfa818fbb1
commit f81d61c10b
8 changed files with 108 additions and 38 deletions

2
Cargo.lock generated
View File

@@ -554,7 +554,7 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pmoutils"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"get_if_addrs",
"netstat2",

View File

@@ -1,6 +1,6 @@
[package]
name = "pmoutils"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
description = "Utilitaires système pour la gestion des adresses IP et des processus"

View File

@@ -12,7 +12,7 @@ BLUE = \033[1;34m
RED = \033[0;31m
NC = \033[0m
.DEFAULT_GOAL := simd
.DEFAULT_GOAL := release
.PHONY: all help build release debug test doc clean install check fmt clippy watch simd scalar
@@ -127,12 +127,16 @@ bump-version:
echo " Nouvelle version: $$new_version"; \
sed -i.bak "s/^version = \"$$current\"/version = \"$$new_version\"/" Cargo.toml && \
rm Cargo.toml.bak && \
echo "$$new_version" > version.txt
@echo "$(GREEN)✓ Version mise à jour dans Cargo.toml et version.txt$(NC)"
echo "$$new_version" > version.txt && \
sed -i.bak "s/pmoutils = \"$$major\.\"/pmoutils = \"$$new_version\"/" README.md && \
rm README.md.bak
@echo "$(GREEN)✓ Version mise à jour dans Cargo.toml, version.txt et README.md$(NC)"
version.txt: Cargo.toml
@echo "$(YELLOW)→ Synchronisation de version.txt...$(NC)"
@grep '^version = ' Cargo.toml | head -n 1 | sed 's/version = "\(.*\)"/\1/' > version.txt
@grep '^version = ' Cargo.toml | head -n 1 | sed 's/version = "\(.*\)"/\1/' > version.txt && \
sed -i.bak "s/pmoutils = \"$$major\.\"/pmoutils = \"$$new_version\"/" README.md && \
rm README.md.bak
@echo "$(GREEN)✓ version.txt synchronisé: $$(cat version.txt)$(NC)"
bench:

View File

@@ -3,6 +3,9 @@
[![Crates.io](https://img.shields.io/crates/v/pmoutils)](https://crates.io/crates/pmoutils)
[![Docs.rs](https://img.shields.io/docsrs/pmoutils)](https://docs.rs/pmoutils)
[![Pmo Crates](https://img.shields.io/crates/v/pmoutils)](https://crates.io/crates/pmoutils)
[![Docs.rs](https://img.shields.io/docsrs/pmoutils)](https://docs.rs/pmoutils)
Utilitaires système pour la gestion des adresses IP réseau et des processus.
## Fonctionnalités

View File

@@ -1,5 +1,6 @@
use get_if_addrs::get_if_addrs;
use std::net::UdpSocket;
use std::time::Duration;
/// Devine l'adresse IP locale de la machine.
///
@@ -10,7 +11,7 @@ use std::net::UdpSocket;
/// # Fonctionnement
///
/// 1. Crée un socket UDP lié à `0.0.0.0:0` (n'importe quelle interface, port aléatoire)
/// 2. Tente une connexion (non effective pour UDP) vers `8.8.8.8:80`
/// 2. Tente une connexion (non effective pour UDP) vers `8.8.8.8:53` (port DNS standard)
/// 3. Récupère l'adresse IP locale du socket
/// 4. En cas d'échec à n'importe quelle étape, retourne `127.0.0.1`
///
@@ -36,7 +37,44 @@ use std::net::UdpSocket;
pub fn guess_local_ip() -> String {
match UdpSocket::bind("0.0.0.0:0") {
Ok(socket) => {
if socket.connect("8.8.8.8:80").is_ok() {
if socket.connect("8.8.8.8:53").is_ok() {
if let Ok(local_addr) = socket.local_addr() {
return local_addr.ip().to_string();
}
}
"127.0.0.1".to_string()
}
Err(_) => "127.0.0.1".to_string(),
}
}
/// Devine l'adresse IP locale de la machine avec un timeout configurable.
///
/// Cette fonction est une version améliorée de [`guess_local_ip`] qui permet
/// de spécifier un timeout pour la connexion.
///
/// # Arguments
///
/// * `timeout` - Durée maximale d'attente pour la connexion
///
/// # Returns
///
/// Retourne l'adresse IP locale sous forme de `String`, ou `"127.0.0.1"` en cas d'échec.
///
/// # Examples
///
/// ```
/// use pmoutils::guess_local_ip_with_timeout;
/// use std::time::Duration;
///
/// let ip = guess_local_ip_with_timeout(Duration::from_secs(2));
/// println!("IP locale détectée: {}", ip);
/// ```
pub fn guess_local_ip_with_timeout(timeout: Duration) -> String {
match UdpSocket::bind("0.0.0.0:0") {
Ok(socket) => {
socket.set_read_timeout(Some(timeout)).ok();
if socket.connect("8.8.8.8:53").is_ok() {
if let Ok(local_addr) = socket.local_addr() {
return local_addr.ip().to_string();
}

View File

@@ -6,30 +6,31 @@
/// # Fonctions principales
///
/// - [`guess_local_ip`] : Devine l'adresse IP locale utilisée pour les connexions sortantes
/// - [`guess_local_ip_with_timeout`] : Version avec timeout configurable
/// - `list_all_ips` : Liste toutes les adresses IP non-loopback des interfaces réseau
///
/// # Examples
///
/// ```
/// use pmoutils::guess_local_ip;
/// use pmoutils::ip_utils::list_all_ips;
///
/// let ip = guess_local_ip();
/// println!("Adresse IP locale: {}", ip);
///
/// let ips = list_all_ips();
/// for (interface, addresses) in ips.iter() {
/// println!("Interface {}: {:?}", interface, addresses);
/// }
/// ```
pub mod ip_utils;
pub use ip_utils::guess_local_ip;
pub use ip_utils::{guess_local_ip, guess_local_ip_with_timeout};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_os_string_format() {
let os = get_os_string();
assert!(!os.is_empty());
assert!(os.contains("/"));
}
#[test]
fn test_get_os_string_contains_os_type() {
let os = get_os_string();
@@ -45,20 +46,51 @@ mod tests {
}
}
/// Utilitaires pour la gestion des processus et des ports réseau.
///
/// Ce module fournit des fonctions pour identifier les processus qui utilisent
/// des ports réseau spécifiques.
///
/// # Fonctions principales
///
/// - [`find_process_using_port`] : Trouve le processus qui écoute sur un port donné
/// - [`ProcessPortInfo`] : Structure contenant les informations d'un processus
/// - [`TransportProtocol`] : Énumération des protocoles TCP et UDP
///
/// # Examples
///
/// ```
/// use pmoutils::{find_process_using_port, TransportProtocol};
///
/// let info = find_process_using_port(TransportProtocol::Tcp, 8080);
///
/// if let Some(process_info) = info {
/// println!("PID: {}", process_info.pid);
/// println!("Nom: {}", process_info.process_name);
/// println!("Propriétaire: {}", process_info.owner);
/// }
/// ```
pub mod process;
pub use process::{find_process_using_port, ProcessPortInfo, TransportProtocol};
/// Retourne une chaîne décrivant le système d'exploitation et sa version.
///
/// Utilise la crate `os_info` pour obtenir de manière portable et fiable
/// les informations sur le système d'exploitation courant.
///
/// # Format
///
/// - macOS: "macOS/15.1" ou "Mac OS/10.15.7"
/// - Linux: "Linux/6.5.0" ou "Ubuntu/22.04"
/// - Windows: "Windows/10.0.19045"
/// - Autre: "{OS}/Unknown"
///
/// # Exemples
/// # Returns
///
/// Une chaîne de caractères au format "Type/Version".
///
/// # Examples
///
/// ```
/// use pmoutils::get_os_string;

View File

@@ -20,7 +20,7 @@ pub enum TransportProtocol {
/// Tente de trouver le processus qui écoute sur `port` pour le protocole donné.
///
/// Retourne `Some(ProcessPortInfo)` si un processus a pu être identifié, sinon `None`.
pub fn find_process_using_port(port: u16, protocol: TransportProtocol) -> Option<ProcessPortInfo> {
pub fn find_process_using_port(protocol: TransportProtocol, port: u16) -> Option<ProcessPortInfo> {
let proto_flag = match protocol {
TransportProtocol::Tcp => ProtocolFlags::TCP,
TransportProtocol::Udp => ProtocolFlags::UDP,
@@ -37,27 +37,19 @@ pub fn find_process_using_port(port: u16, protocol: TransportProtocol) -> Option
system.refresh_all();
for socket in sockets {
match socket.protocol_socket_info {
ProtocolSocketInfo::Tcp(ref tcp_info)
if matches!(protocol, TransportProtocol::Tcp) && tcp_info.local_port == port =>
{
let port_match = match (&socket.protocol_socket_info, protocol) {
(ProtocolSocketInfo::Tcp(tcp), TransportProtocol::Tcp) => tcp.local_port == port,
(ProtocolSocketInfo::Udp(udp), TransportProtocol::Udp) => udp.local_port == port,
_ => false,
};
if port_match {
if let Some(info) =
build_process_info(&mut system, port, socket.associated_pids.first())
{
return Some(info);
}
}
ProtocolSocketInfo::Udp(ref udp_info)
if matches!(protocol, TransportProtocol::Udp) && udp_info.local_port == port =>
{
if let Some(info) =
build_process_info(&mut system, port, socket.associated_pids.first())
{
return Some(info);
}
}
_ => continue,
}
}
None
@@ -68,7 +60,7 @@ fn build_process_info(
port: u16,
pid_opt: Option<&u32>,
) -> Option<ProcessPortInfo> {
let pid = *pid_opt?;
let pid = pid_opt.copied()?;
let process = system.process(Pid::from_u32(pid))?;
let process_name = process.name().to_string();
@@ -133,7 +125,7 @@ mod tests {
#[test]
fn test_find_process_using_port_invalid() {
let result = find_process_using_port(65535, TransportProtocol::Tcp);
let result = find_process_using_port(TransportProtocol::Tcp, 65535);
assert!(result.is_none() || result.is_some());
}

1
version.txt Normal file
View File

@@ -0,0 +1 @@
0.1.1