From 088419dde5af2016e8cfba6eae52537dc78eb409 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 01:35:33 +0100 Subject: [PATCH 01/12] add source_ip --- src/http/server.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/http/server.rs b/src/http/server.rs index bdd02d18e6a..1d0ebcc066c 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -35,6 +35,8 @@ use core::cell::UnsafeCell; use core::fmt::Debug; use core::marker::PhantomData; +use core::mem; +use core::net::Ipv4Addr; use core::sync::atomic::{AtomicBool, Ordering}; use core::time::*; use core::{ffi, ptr}; @@ -799,6 +801,58 @@ impl EspHttpRawConnection<'_> { Ok(()) } + + /// Retrieves the source ip of the request. + /// + /// The ip is retrieved using the underlying session socket. + pub fn source_ip(&mut self) -> Result { + unsafe { + let sockfd = httpd_req_to_sockfd(self.0 as *mut _); + + if sockfd == -1 { + //Unwrap is fine, this cannot fail. + return Err(EspError::from(-1).unwrap()); + } + + let mut address = sockaddr_in { + sin_len: mem::size_of::() as u8, + sin_family: AF_INET as u8, + sin_port: 0, + sin_addr: in_addr { s_addr: 0 }, + sin_zero: [0; 8], + }; + + let mut addr_len = mem::size_of::() as socklen_t; + + esp!(lwip_getpeername( + sockfd, + &mut address as *mut _ as *mut sockaddr, + &mut addr_len, + ))?; + + //"255.255.255.255\0" = 16 bytes + let mut ip_string = [0i8; 16]; + + if lwip_inet_ntop( + AF_INET as _, + &address.sin_addr as *const _ as *const _, + ip_string.as_mut_ptr(), + ip_string.len() as _, + ) + .is_null() + { + return Err(EspError::from(-1).unwrap()); + } + + let ip: Ipv4Addr = CStr::from_ptr(ip_string.as_ptr()) + .to_str() + .map_err(|_| EspError::from(-1).unwrap())? + .parse() + .map_err(|_| EspError::from(-1).unwrap())?; + + Ok(ip) + } + } } impl RawHandle for EspHttpRawConnection<'_> { From 5cced1a84350e0845457b2708fb6c620168c3e78 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 01:47:59 +0100 Subject: [PATCH 02/12] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3544397cec9..74925daeb28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow using esp timer with skip_unhandled_events (#526) - OTA - Implements a new type `EspFirmwareInfoLoad` that has a reduced memory consumption (#531) - Added set_promiscuous function in EthDriver (#246) +- Add source_ip function in EspHttpRawConnection (#538) ### Fixed - The alloc::Vec version stomps the scan state from Done to Idle. (#459) From 88626159661621ab157b871925b6260c90ef8fbb Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:02:14 +0100 Subject: [PATCH 03/12] add ipv4 cfg, fix platform bug --- src/http/server.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index 1d0ebcc066c..d3c6004b9e4 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -802,10 +802,11 @@ impl EspHttpRawConnection<'_> { Ok(()) } - /// Retrieves the source ip of the request. + /// Retrieves the source IPv4 of the request. /// - /// The ip is retrieved using the underlying session socket. - pub fn source_ip(&mut self) -> Result { + /// The IPv4 is retrieved using the underlying session socket. + #[cfg(esp_idf_lwip_ipv4)] + pub fn source_ip4(&mut self) -> Result { unsafe { let sockfd = httpd_req_to_sockfd(self.0 as *mut _); @@ -830,13 +831,14 @@ impl EspHttpRawConnection<'_> { &mut addr_len, ))?; + //We use c_char to be platform independent //"255.255.255.255\0" = 16 bytes - let mut ip_string = [0i8; 16]; + let mut ip_string: [ffi::c_char; 16] = [0; 16]; if lwip_inet_ntop( AF_INET as _, &address.sin_addr as *const _ as *const _, - ip_string.as_mut_ptr(), + &mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char, ip_string.len() as _, ) .is_null() @@ -844,11 +846,12 @@ impl EspHttpRawConnection<'_> { return Err(EspError::from(-1).unwrap()); } - let ip: Ipv4Addr = CStr::from_ptr(ip_string.as_ptr()) - .to_str() - .map_err(|_| EspError::from(-1).unwrap())? - .parse() - .map_err(|_| EspError::from(-1).unwrap())?; + let ip: Ipv4Addr = + CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char) + .to_str() + .map_err(|_| EspError::from(-1).unwrap())? + .parse() + .map_err(|_| EspError::from(-1).unwrap())?; Ok(ip) } From cba4e0cc3b2359e7d819f1bef1c19f16d675a343 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:21:39 +0100 Subject: [PATCH 04/12] add ipv6, gatekeep --- src/http/server.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/http/server.rs b/src/http/server.rs index d3c6004b9e4..3d53ce147f7 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -35,8 +35,12 @@ use core::cell::UnsafeCell; use core::fmt::Debug; use core::marker::PhantomData; +#[cfg(any(esp_idf_lwip_ipv4, esp_idf_lwip_ipv6))] use core::mem; +#[cfg(esp_idf_lwip_ipv4)] use core::net::Ipv4Addr; +#[cfg(esp_idf_lwip_ipv6)] +use core::net::Ipv6Addr; use core::sync::atomic::{AtomicBool, Ordering}; use core::time::*; use core::{ffi, ptr}; @@ -856,6 +860,62 @@ impl EspHttpRawConnection<'_> { Ok(ip) } } + + /// Retrieves the source IPv6 of the request. + /// + /// The IPv6 is retrieved using the underlying session socket. + #[cfg(esp_idf_lwip_ipv6)] + pub fn source_ip6(&mut self) -> Result { + unsafe { + let sockfd = httpd_req_to_sockfd(self.0 as *mut _); + + if sockfd == -1 { + // Unwrap is fine, this cannot fail. + return Err(EspError::from(-1).unwrap()); + } + + let mut address = sockaddr_in6 { + sin6_len: mem::size_of::() as u8, + sin6_family: AF_INET6 as u8, + sin6_port: 0, + sin6_addr: in6_addr { + un: in6_addr__bindgen_ty_1 { u8_addr: [0; 16] }, + }, + sin6_flowinfo: 0, + sin6_scope_id: 0, + }; + + let mut addr_len = mem::size_of::() as socklen_t; + + esp!(lwip_getpeername( + sockfd, + &mut address as *mut _ as *mut sockaddr, + &mut addr_len, + ))?; + + // IPv6 address = 39 bytes + null terminator + let mut ip_string: [ffi::c_char; 40] = [0; 40]; + + if lwip_inet_ntop( + AF_INET6 as _, + &address.sin6_addr as *const _ as *const _, + ip_string.as_mut_ptr(), + ip_string.len() as _, + ) + .is_null() + { + return Err(EspError::from(-1).unwrap()); + } + + let ip: Ipv6Addr = CStr::from_ptr(ip_string.as_ptr()) + .to_str() + .map_err(|_| EspError::from(-1).unwrap())? + .parse() + .map_err(|_| EspError::from(-1).unwrap())?; + + Ok(ip) + } + } } impl RawHandle for EspHttpRawConnection<'_> { From 7671457287cbac1f7630bec0f49192e2a233eb19 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:22:30 +0100 Subject: [PATCH 05/12] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74925daeb28..2f6b52e8c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow using esp timer with skip_unhandled_events (#526) - OTA - Implements a new type `EspFirmwareInfoLoad` that has a reduced memory consumption (#531) - Added set_promiscuous function in EthDriver (#246) -- Add source_ip function in EspHttpRawConnection (#538) +- Add source_ip4, source_ip6 function in EspHttpRawConnection (#538) ### Fixed - The alloc::Vec version stomps the scan state from Done to Idle. (#459) From 5f86b0fe556a6ca4622424386e4e9e9f461badc2 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:27:33 +0100 Subject: [PATCH 06/12] parity --- src/http/server.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index 3d53ce147f7..4001199b25c 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -893,13 +893,14 @@ impl EspHttpRawConnection<'_> { &mut addr_len, ))?; + //We use c_char to be platform independent // IPv6 address = 39 bytes + null terminator let mut ip_string: [ffi::c_char; 40] = [0; 40]; if lwip_inet_ntop( AF_INET6 as _, &address.sin6_addr as *const _ as *const _, - ip_string.as_mut_ptr(), + &mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char, ip_string.len() as _, ) .is_null() @@ -907,7 +908,7 @@ impl EspHttpRawConnection<'_> { return Err(EspError::from(-1).unwrap()); } - let ip: Ipv6Addr = CStr::from_ptr(ip_string.as_ptr()) + let ip: Ipv6Addr = CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char) .to_str() .map_err(|_| EspError::from(-1).unwrap())? .parse() From 1df476a4068aca155446cde3683937de4b719a96 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:36:27 +0100 Subject: [PATCH 07/12] format --- src/http/server.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index 4001199b25c..c1ebc645ea8 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -908,11 +908,12 @@ impl EspHttpRawConnection<'_> { return Err(EspError::from(-1).unwrap()); } - let ip: Ipv6Addr = CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char) - .to_str() - .map_err(|_| EspError::from(-1).unwrap())? - .parse() - .map_err(|_| EspError::from(-1).unwrap())?; + let ip: Ipv6Addr = + CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char) + .to_str() + .map_err(|_| EspError::from(-1).unwrap())? + .parse() + .map_err(|_| EspError::from(-1).unwrap())?; Ok(ip) } From bd299cbecb3383149f7a7fc6549b984d6637ace5 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:38:57 +0100 Subject: [PATCH 08/12] remove import --- src/http/server.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index c1ebc645ea8..fd35bafe6f3 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -35,8 +35,6 @@ use core::cell::UnsafeCell; use core::fmt::Debug; use core::marker::PhantomData; -#[cfg(any(esp_idf_lwip_ipv4, esp_idf_lwip_ipv6))] -use core::mem; #[cfg(esp_idf_lwip_ipv4)] use core::net::Ipv4Addr; #[cfg(esp_idf_lwip_ipv6)] @@ -820,14 +818,14 @@ impl EspHttpRawConnection<'_> { } let mut address = sockaddr_in { - sin_len: mem::size_of::() as u8, + sin_len: core::mem::size_of::() as u8, sin_family: AF_INET as u8, sin_port: 0, sin_addr: in_addr { s_addr: 0 }, sin_zero: [0; 8], }; - let mut addr_len = mem::size_of::() as socklen_t; + let mut addr_len = core::mem::size_of::() as socklen_t; esp!(lwip_getpeername( sockfd, From ca0b8fad8faf0fd51aea2e1ad4e017890809c880 Mon Sep 17 00:00:00 2001 From: _index Date: Sat, 28 Dec 2024 17:39:32 +0100 Subject: [PATCH 09/12] fix --- src/http/server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index fd35bafe6f3..8a7efa3ae9e 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -873,7 +873,7 @@ impl EspHttpRawConnection<'_> { } let mut address = sockaddr_in6 { - sin6_len: mem::size_of::() as u8, + sin6_len: core::mem::size_of::() as u8, sin6_family: AF_INET6 as u8, sin6_port: 0, sin6_addr: in6_addr { @@ -883,7 +883,7 @@ impl EspHttpRawConnection<'_> { sin6_scope_id: 0, }; - let mut addr_len = mem::size_of::() as socklen_t; + let mut addr_len = core::mem::size_of::() as socklen_t; esp!(lwip_getpeername( sockfd, From fd013d4b49ad08aa45c351aea9903b56677a156b Mon Sep 17 00:00:00 2001 From: _index Date: Sun, 29 Dec 2024 03:22:03 +0100 Subject: [PATCH 10/12] cleanup --- src/http/server.rs | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index 8a7efa3ae9e..92810b2c905 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -808,38 +808,34 @@ impl EspHttpRawConnection<'_> { /// /// The IPv4 is retrieved using the underlying session socket. #[cfg(esp_idf_lwip_ipv4)] - pub fn source_ip4(&mut self) -> Result { + pub fn source_ip4(&self) -> Result { unsafe { - let sockfd = httpd_req_to_sockfd(self.0 as *mut _); + let sockfd = httpd_req_to_sockfd(self.handle()); if sockfd == -1 { - //Unwrap is fine, this cannot fail. return Err(EspError::from(-1).unwrap()); } - let mut address = sockaddr_in { + let mut addr = sockaddr_in { sin_len: core::mem::size_of::() as u8, sin_family: AF_INET as u8, - sin_port: 0, - sin_addr: in_addr { s_addr: 0 }, - sin_zero: [0; 8], + ..Default::default() }; let mut addr_len = core::mem::size_of::() as socklen_t; esp!(lwip_getpeername( sockfd, - &mut address as *mut _ as *mut sockaddr, + &mut addr as *mut _ as *mut sockaddr, &mut addr_len, ))?; - //We use c_char to be platform independent //"255.255.255.255\0" = 16 bytes let mut ip_string: [ffi::c_char; 16] = [0; 16]; if lwip_inet_ntop( AF_INET as _, - &address.sin_addr as *const _ as *const _, + &addr.sin_addr as *const _ as *const _, &mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char, ip_string.len() as _, ) @@ -863,41 +859,34 @@ impl EspHttpRawConnection<'_> { /// /// The IPv6 is retrieved using the underlying session socket. #[cfg(esp_idf_lwip_ipv6)] - pub fn source_ip6(&mut self) -> Result { + pub fn source_ip6(&self) -> Result { unsafe { - let sockfd = httpd_req_to_sockfd(self.0 as *mut _); + let sockfd = httpd_req_to_sockfd(self.handle()); if sockfd == -1 { - // Unwrap is fine, this cannot fail. return Err(EspError::from(-1).unwrap()); } - let mut address = sockaddr_in6 { + let mut addr = sockaddr_in6 { sin6_len: core::mem::size_of::() as u8, sin6_family: AF_INET6 as u8, - sin6_port: 0, - sin6_addr: in6_addr { - un: in6_addr__bindgen_ty_1 { u8_addr: [0; 16] }, - }, - sin6_flowinfo: 0, - sin6_scope_id: 0, + ..Default::default() }; let mut addr_len = core::mem::size_of::() as socklen_t; esp!(lwip_getpeername( sockfd, - &mut address as *mut _ as *mut sockaddr, + &mut addr as *mut _ as *mut sockaddr, &mut addr_len, ))?; - //We use c_char to be platform independent // IPv6 address = 39 bytes + null terminator let mut ip_string: [ffi::c_char; 40] = [0; 40]; if lwip_inet_ntop( AF_INET6 as _, - &address.sin6_addr as *const _ as *const _, + &addr.sin6_addr as *const _ as *const _, &mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char, ip_string.len() as _, ) From a13ffa60955c0c48269cb393983604f51cbae1fc Mon Sep 17 00:00:00 2001 From: _index Date: Wed, 1 Jan 2025 14:07:23 +0100 Subject: [PATCH 11/12] fix --- src/http/server.rs | 74 +++++++++------------------------------------- 1 file changed, 14 insertions(+), 60 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index 92810b2c905..310dc0e77a0 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -808,50 +808,27 @@ impl EspHttpRawConnection<'_> { /// /// The IPv4 is retrieved using the underlying session socket. #[cfg(esp_idf_lwip_ipv4)] - pub fn source_ip4(&self) -> Result { + pub fn source_ipv4(&self) -> Result { unsafe { let sockfd = httpd_req_to_sockfd(self.handle()); if sockfd == -1 { - return Err(EspError::from(-1).unwrap()); + return Err(EspError::from_infallible::()); } let mut addr = sockaddr_in { - sin_len: core::mem::size_of::() as u8, - sin_family: AF_INET as u8, + sin_len: core::mem::size_of::() as _, + sin_family: AF_INET as _, ..Default::default() }; - let mut addr_len = core::mem::size_of::() as socklen_t; - esp!(lwip_getpeername( sockfd, - &mut addr as *mut _ as *mut sockaddr, - &mut addr_len, + &mut addr as *mut _ as *mut _, + &mut core::mem::size_of::() as *mut _ as *mut _, ))?; - //"255.255.255.255\0" = 16 bytes - let mut ip_string: [ffi::c_char; 16] = [0; 16]; - - if lwip_inet_ntop( - AF_INET as _, - &addr.sin_addr as *const _ as *const _, - &mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char, - ip_string.len() as _, - ) - .is_null() - { - return Err(EspError::from(-1).unwrap()); - } - - let ip: Ipv4Addr = - CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char) - .to_str() - .map_err(|_| EspError::from(-1).unwrap())? - .parse() - .map_err(|_| EspError::from(-1).unwrap())?; - - Ok(ip) + Ok(Ipv4Addr::from(addr.sin_addr.s_addr)) } } @@ -859,50 +836,27 @@ impl EspHttpRawConnection<'_> { /// /// The IPv6 is retrieved using the underlying session socket. #[cfg(esp_idf_lwip_ipv6)] - pub fn source_ip6(&self) -> Result { + pub fn source_ipv6(&self) -> Result { unsafe { let sockfd = httpd_req_to_sockfd(self.handle()); if sockfd == -1 { - return Err(EspError::from(-1).unwrap()); + return Err(EspError::from_infallible::()); } let mut addr = sockaddr_in6 { - sin6_len: core::mem::size_of::() as u8, - sin6_family: AF_INET6 as u8, + sin6_len: core::mem::size_of::() as _, + sin6_family: AF_INET6 as _, ..Default::default() }; - let mut addr_len = core::mem::size_of::() as socklen_t; - esp!(lwip_getpeername( sockfd, - &mut addr as *mut _ as *mut sockaddr, - &mut addr_len, + &mut addr as *mut _ as *mut _, + &mut core::mem::size_of::() as *mut _ as *mut _, ))?; - // IPv6 address = 39 bytes + null terminator - let mut ip_string: [ffi::c_char; 40] = [0; 40]; - - if lwip_inet_ntop( - AF_INET6 as _, - &addr.sin6_addr as *const _ as *const _, - &mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char, - ip_string.len() as _, - ) - .is_null() - { - return Err(EspError::from(-1).unwrap()); - } - - let ip: Ipv6Addr = - CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char) - .to_str() - .map_err(|_| EspError::from(-1).unwrap())? - .parse() - .map_err(|_| EspError::from(-1).unwrap())?; - - Ok(ip) + Ok(Ipv6Addr::from(addr.sin6_addr.un.u8_addr)) } } } From e5331e4264d1df4610066d08a9adf3d749bced5d Mon Sep 17 00:00:00 2001 From: _index Date: Wed, 1 Jan 2025 14:10:20 +0100 Subject: [PATCH 12/12] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 762ff61b64a..e7d20fbdf40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - OTA - Implements a new type `EspFirmwareInfoLoad` that has a reduced memory consumption (#531) - Added set_promiscuous function in EthDriver (#246) - Added set_promiscuous, is_promiscuous functions in WifiDriver (#246) -- Add source_ip4, source_ip6 function in EspHttpRawConnection (#538) +- Added source_ipv4, source_ipv6 function in EspHttpRawConnection (#538) ### Fixed - The alloc::Vec version stomps the scan state from Done to Idle. (#459)