Repository: lemunozm/message-io (language: rust)

Issue:
Modify some parameters of udp connection
Hi,

I noticed that '0.0.0.0:0' is used in the code, which means a random port is assigned. Is there some way I can bind UDP to a specified port?

```rust
fn connect(remote_addr: RemoteAddr) -> io::Result<ConnectionInfo<Self>> {
    let socket = UdpSocket::bind("0.0.0.0:0".parse().unwrap())?;
    let peer_addr = *remote_addr.socket_addr();
    socket.connect(peer_addr)?;
    let local_addr = socket.local_addr()?;
    Ok(ConnectionInfo { remote: RemoteResource { socket }, local_addr, peer_addr })
}
```

Also, can I set some timeout on read/write, for example using set_read_timeout()/set_write_timeout().


Discussion / hints:
HI @Be33eD, yes it's hardcoded when you perform an output connection. When you listen, you can specify the port. 

This more "advance" configuration, along with the timeout configuration is not supported currently in `message-io`. There is an [open issue](https://github.com/lemunozm/message-io/issues/54) where I wanted to add some configuration transport-related properties at connect/listen calls. In those configurations, you could specify these kinds of things as local port, timeouts, etc. 

Currently, I do not have time to tackle new features on `message-io`, only some bugs/issues. Maybe in a near future. Sorry for the inconvenience. Of course, if any brave person wants to make a PR with this, I will give them all my support.
Thanks a lot for your reply and work on message-io, it's a really great library.

I will continue to try other ways to solve this problem.

Fix patch:
diff --git a/src/adapters/udp.rs b/src/adapters/udp.rs
index 4639285..4e446e0 100644
--- a/src/adapters/udp.rs
+++ b/src/adapters/udp.rs
@@ -26,12 +26,24 @@ pub const MAX_LOCAL_PAYLOAD_LEN: usize = 65535 - 20 - 8;
 #[cfg(target_os = "macos")]
 pub const MAX_LOCAL_PAYLOAD_LEN: usize = 9216 - 20 - 8;
 
-#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct UdpConnectConfig {
+    /// Specify the source address and port.
+    pub source_address: SocketAddr,
+
     /// Enables the socket capabilities to send broadcast messages.
     pub broadcast: bool,
 }
 
+impl Default for UdpConnectConfig {
+    fn default() -> Self {
+        Self {
+            source_address: SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0).into(),
+            broadcast: false,
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
 pub struct UdpListenConfig {
     /// Enables the socket capabilities to send broadcast messages when the listening socket is
@@ -66,7 +78,7 @@ impl Remote for RemoteResource {
             _ => panic!("Internal error: Got wrong config"),
         };
 
-        let socket = UdpSocket::bind("0.0.0.0:0".parse().unwrap())?;
+        let socket = UdpSocket::bind(config.source_address)?;
         let peer_addr = *remote_addr.socket_addr();
 
         if config.broadcast {
diff --git a/src/network.rs b/src/network.rs
index 0dbf1ac..78326ba 100644
--- a/src/network.rs
+++ b/src/network.rs
@@ -126,7 +126,7 @@ impl NetworkController {
     /// let (handler, listener) = node::split();
     /// handler.signals().send_with_timer((), std::time::Duration::from_secs(1));
     ///
-    /// let config = UdpConnectConfig { broadcast: true };
+    /// let config = UdpConnectConfig { broadcast: true, ..Default::default() };
     /// let addr = "255.255.255.255:7777";
     /// let (conn_endpoint, _) = handler.network().connect_with(TransportConnect::Udp(config), addr).unwrap();
     /// // The socket could not be able to send yet.
@@ -226,7 +226,7 @@ impl NetworkController {
     /// let (handler, listener) = node::split();
     /// handler.signals().send_with_timer((), std::time::Duration::from_secs(1));
     ///
-    /// let config = UdpConnectConfig { broadcast: true };
+    /// let config = UdpConnectConfig { broadcast: true, ..Default::default() };
     /// let addr = "255.255.255.255:7777";
     /// match handler.network().connect_sync_with(TransportConnect::Udp(config), addr) {
     ///     Ok((endpoint, _)) => {


Test patch: