Skip to content

Commit

Permalink
Issue-134 - Use reentrant functions for service lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
morisja committed Oct 10, 2024
1 parent 0dde697 commit 1a0c97b
Showing 1 changed file with 60 additions and 28 deletions.
88 changes: 60 additions & 28 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ use slog::{debug, error, Logger};
use std::mem::size_of;
use std::str::FromStr;
use std::num::ParseIntError;
use std::mem;
use std::ptr;

use crate::ffi::{gethostbyaddr_r, gethostbyname2_r, Hostent, LibcIp, HostentError};
use crate::protocol::{AiResponse, AiResponseHeader};
Expand All @@ -38,7 +40,7 @@ use super::protocol;
use super::protocol::RequestType;


use nix::libc::{c_char, c_int, getservbyname, getservbyport, servent, size_t};
use nix::libc::{c_char, c_int, servent, size_t};

mod nixish;
use nixish::{Netgroup, Service};
Expand All @@ -60,6 +62,22 @@ extern "C" {
user: *const c_char,
domain: *const c_char,
) -> c_int;
fn getservbyname_r(
name: *const c_char,
proto: *const c_char,
result_buf: *mut servent,
buf: *mut c_char,
buflen: size_t,
result: *mut *mut servent,
) -> c_int;
fn getservbyport_r(
port: c_int,
proto: *const c_char,
result_buf: *mut servent,
buf: *mut c_char,
buflen: size_t,
result: *mut *mut servent,
) -> c_int;
}
#[derive(Debug)]
pub struct ServiceWithName {
Expand Down Expand Up @@ -107,25 +125,30 @@ impl FromStr for ServiceWithName {

impl ServiceWithName {
fn lookup(&self) -> Result<Option<Service>> {
let serv_entry: *const servent;
let service_cstr = CString::new(self.service.as_str())?;
let proto_cstr = self.proto.as_ref().map(|s| CString::new(s.as_str()).unwrap());
let service_ptr=service_cstr.as_ptr();
let proto_ptr = proto_cstr.as_ref().map_or(ptr::null(), |s| s.as_ptr());

if let Some(protocol) = &self.proto {
serv_entry = unsafe {
getservbyname(
self.service.as_ptr() as *const c_char,
protocol.as_ptr() as *const c_char,
)
};
} else {
serv_entry =
unsafe { getservbyname(self.service.as_ptr() as *const c_char, std::ptr::null()) };
}
let mut result_buf: servent = unsafe { mem::zeroed() };
let mut buffer: Vec<c_char> = vec![0; 1024];
let mut result: *mut servent = ptr::null_mut();

if serv_entry.is_null() {
Ok(None)
} else {
let service = unsafe { *serv_entry }.try_into()?;
let ret = unsafe {
getservbyname_r(
service_ptr,
proto_ptr,
&mut result_buf,
buffer.as_mut_ptr(),
buffer.len(),
& mut result
)
};
if ret == 0 && !result.is_null() {
let service: Service = unsafe { *result }.try_into()?;
Ok(Some(service))
} else {
Ok(None)
}
}
}
Expand Down Expand Up @@ -155,19 +178,28 @@ impl FromStr for ServiceWithPort {

impl ServiceWithPort {
fn lookup(&self) -> Result<Option<Service>> {
let serv_entry: *const servent;
if let Some(protocol) = &self.proto {
serv_entry =
unsafe { getservbyport(self.port as c_int, protocol.as_ptr() as *const c_char) };
} else {
serv_entry = unsafe { getservbyport(self.port as c_int, std::ptr::null()) };
}
let proto_cstr = self.proto.as_ref().map(|s| CString::new(s.as_str()).unwrap());
let proto_ptr = proto_cstr.as_ref().map_or(ptr::null(), |s| s.as_ptr());

if serv_entry.is_null() {
Ok(None)
} else {
let service = unsafe { *serv_entry }.try_into()?;
let mut result_buf: servent = unsafe { mem::zeroed() };
let mut buffer: Vec<c_char> = vec![0; 1024];
let mut result: *mut servent = ptr::null_mut();

let ret = unsafe {
getservbyport_r(
self.port as c_int,
proto_ptr,
&mut result_buf,
buffer.as_mut_ptr(),
buffer.len(),
& mut result
)
};
if ret == 0 && !result.is_null() {
let service: Service = unsafe { *result }.try_into()?;
Ok(Some(service))
} else {
Ok(None)
}
}
}
Expand Down

0 comments on commit 1a0c97b

Please sign in to comment.