Search code examples
rusttcputf-8streamvpn

Encode utf8 on TcpStream


I am trying to route all my traffic by Iptables .

iptables -t nat -D OUTPUT -p tcp -j DNAT --to-destination 127.0.0.1:3400

to my Rust Code which is listening on specific port

    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);
    }

then i want to read my data which UTF8 and i faced this such error .

thread 'main' panicked at 'result decode failed: Utf8Error { valid_up_to: 8, error_len: Some(1) }', src/main.rs:46:50

How can i resolve this error or how can i get data of requested ?

Thanks for your helping.


Solution

  • Since utf8 encoded strings' chars can vary in length from 1 to 4 bytes, when you are getting transfer over the network (or in other streaming way) it can happen, that packet (or the buffer you read into) is divided in the middle of a character. Rust requires that str and String types contains only valid utf8 encoded characters, so when you are trying to interpret the bytes as utf8 string it returns error.

    Luckily this error type Utf8Error contains information about until which byte this byte slice is valid utf8. So you can use only the first, correct part, and the rest concatenate with further data. You can see the example of that in the linked documentation.

    Also, you don't have to use unsafe slice::from_raw_parts_mut, just use &mut buffer.