Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UdpSocket.send_to fails with "invalid argument"

Tags:

sockets

rust

udp

I came across this problem while experimenting with BitTorrent tracker protocol using Rust.

This simple program that is supposed to send some data using UDP sockets is failing:

use std::collections::HashSet;
use std::io::net::addrinfo;
use std::io::net::ip::{Ipv4Addr, SocketAddr, IpAddr};
use std::io::net::udp::UdpSocket;

fn main() {
    let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
    let mut socket = match UdpSocket::bind(addr) {
        Ok(s) => s,
        Err(e) => panic!("couldn't bind socket: {}", e),
    };

    let host_addr = "tracker.openbittorrent.com";
    let port = "80";

    let host_ips: HashSet<IpAddr> =
        addrinfo::get_host_addresses(host_addr.as_slice()).unwrap().into_iter().collect();

    for host_ip in host_ips.into_iter() {
        let socket_addr = SocketAddr {
            ip: host_ip,
            port: from_str(port).unwrap(),
        };
        println!("Sending to {}", socket_addr);
        let data: &[u8] = [0x1, 0x2, 0x3];
        println!("{}", socket.send_to(data, socket_addr));
    }
}

Output:

Sending to 31.172.63.252:80
Err(invalid argument (Invalid argument))
Sending to 31.172.63.253:80
Err(invalid argument (Invalid argument))

Any ideas about what's going wrong?

like image 928
sinan Avatar asked Nov 04 '14 10:11

sinan


1 Answers

You are binding the socket to localhost (the loopback interface), and then trying to communicate through that socket to an address not on that interface. If you instead bind to 0.0.0.0, it will succeed. This means "all ipv4 interfaces". You can bind to a more specific address if necessary.

like image 120
Corey Richardson Avatar answered Nov 02 '22 11:11

Corey Richardson