Я пытаюсь направить весь свой трафик с помощью Iptables.
iptables -t nat -D OUTPUT -p tcp -j DNAT --to-destination 127.0.0.1:3400
к моему коду Rust, который прослушивает определенный порт
let addrs = [
SocketAddr::from(([127, 0, 0, 1], 3400)),
];
let tcp = TcpListener::bind(&addrs[..]).expect("error bind tcp");
match tcp.accept() {
Ok((_socket,addr)) => println!("{:?} ",addr),
Err(_) => println!("error found"),
}
let mut buffer = [0;500];
let mut buf = unsafe {
slice::from_raw_parts_mut((&mut buffer).as_mut_ptr(),buffer.len())
};
for stream in tcp.incoming() {
let buf = stream.unwrap().read(buf).expect("stream read buffer ");
let result = StrType::from_utf8(&buffer).expect("result decode failed");
// println!("{:?} {:?}",buffer,buf);
println!("{:?}",buf);
println!("{}",result.len());
println!("{:?}\n\n",result);
}
затем я хочу прочитать свои данные, которые UTF8, и я столкнулся с такой ошибкой.
thread 'main' panicked at 'result decode failed: Utf8Error { valid_up_to: 8, error_len: Some(1) }', src/main.rs:46:50
Как я могу устранить эту ошибку или как я могу получить запрошенные данные?
Спасибо за вашу помощь.
Поскольку символы строк в кодировке utf8 могут иметь длину от 1 до 4 байтов, когда вы получаете передачу по сети (или другим потоковым способом), может случиться так, что этот пакет (или буфер, в который вы читаете) разделен посередине персонажа. Rust требует, чтобы типы str
и String
содержали только допустимые символы в кодировке utf8, поэтому, когда вы пытаетесь интерпретировать байты как строку utf8, он возвращает ошибку.
К счастью, этот тип ошибки Utf8Error содержит информацию о том, до какого байта этот фрагмент байта действителен utf8. Таким образом, вы можете использовать только первую правильную часть, а остальные объединять с другими данными. Вы можете увидеть пример этого в связанной документации.
Кроме того, вам не нужно использовать небезопасный slice::from_raw_parts_mut
, просто используйте &mut buffer
.
@mwg DNS не является текстовым протоколом. Вы должны анализировать байты как байты, а не как строку UTF8.
@justinas, тогда как можно не анализировать байты как байты с помощью Rust?
@mwg вы бы прочитали пакет DNS в массив байтов, как сейчас. Отличие в том, что вы не будете преобразовывать его в строку, а будете работать с самими байтами в соответствии с протоколом. Также, похоже, существуют ящики, такие как dns_parser, чтобы помочь с этим.
@justinas, кажется, это мой ответ. :)
Спасибо за эту документацию. Например, если я буду запрашивать разрешение DNS в своем коде с помощью этого кода, как можно проанализировать запрос с помощью нечитаемого UTF8? Теперь я могу прочитать первые символы в моем запросе для HTTP, но другие запросы все еще доступны для чтения.