Move public IP address detection out of bash
This commit is contained in:
		@@ -79,3 +79,4 @@ bs58 = "0.2.0"
 | 
				
			|||||||
p2p = "0.5.2"
 | 
					p2p = "0.5.2"
 | 
				
			||||||
futures = "0.1.21"
 | 
					futures = "0.1.21"
 | 
				
			||||||
clap = "2.31"
 | 
					clap = "2.31"
 | 
				
			||||||
 | 
					reqwest = "0.8.6"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,7 +169,7 @@ Runtime configuration files for the daemon can be found in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#### Leader daemon
 | 
					#### Leader daemon
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
$ sudo snap set solana mode=leader public-ip=$(curl -s http://ifconfig.co)
 | 
					$ sudo snap set solana mode=leader
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If CUDA is available:
 | 
					If CUDA is available:
 | 
				
			||||||
@@ -196,18 +196,18 @@ to port tcp:873, tcp:9900 and the port range udp:8000-udp:10000**
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
To run both the Leader and Drone:
 | 
					To run both the Leader and Drone:
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
$ sudo snap set solana mode=leader+drone public-ip=$(curl -s http://ifconfig.co)
 | 
					$ sudo snap set solana mode=leader+drone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### Validator daemon
 | 
					#### Validator daemon
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
$ sudo snap set solana mode=validator public-ip=$(curl -s http://ifconfig.co)
 | 
					$ sudo snap set solana mode=validator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
If CUDA is available:
 | 
					If CUDA is available:
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
$ sudo snap set solana mode=validator public-ip=$(curl -s http://ifconfig.co) enable-cuda=1
 | 
					$ sudo snap set solana mode=validator enable-cuda=1
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
By default the validator will connect to **testnet.solana.com**, override
 | 
					By default the validator will connect to **testnet.solana.com**, override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,53 +1,45 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
num_tokens=1000000000
 | 
					 | 
				
			||||||
public_ip=
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
here=$(dirname "$0")
 | 
					here=$(dirname "$0")
 | 
				
			||||||
# shellcheck source=multinode-demo/common.sh
 | 
					# shellcheck source=multinode-demo/common.sh
 | 
				
			||||||
source "$here"/common.sh
 | 
					source "$here"/common.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
usage () {
 | 
					usage () {
 | 
				
			||||||
  cat <<EOF
 | 
					  cat <<EOF
 | 
				
			||||||
usage: $0 [-n num_tokens] [-P] [-p public_ip_address]
 | 
					usage: $0 [-n num_tokens] [-l] [-p]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Creates a fullnode configuration
 | 
					Creates a fullnode configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 -n num_tokens         - Number of tokens to create
 | 
					 -n num_tokens  - Number of tokens to create
 | 
				
			||||||
 -p public_ip_address  - Public IP address to advertise
 | 
					 -l             - Detect network address from local machine configuration, which
 | 
				
			||||||
                         (default uses the system IP address, which may be
 | 
					                  may be a private IP address unaccessible on the Intenet (default)
 | 
				
			||||||
                          on a private network)
 | 
					 -p             - Detect public address using public Internet servers
 | 
				
			||||||
 -P                    - Autodetect the public IP address of the machine
 | 
					 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
while getopts "h?n:p:P" opt; do
 | 
					ip_address_arg=-l
 | 
				
			||||||
 | 
					num_tokens=1000000000
 | 
				
			||||||
 | 
					while getopts "h?n:lp" opt; do
 | 
				
			||||||
  case $opt in
 | 
					  case $opt in
 | 
				
			||||||
  h|\?)
 | 
					  h|\?)
 | 
				
			||||||
    usage
 | 
					    usage
 | 
				
			||||||
    exit 0
 | 
					    exit 0
 | 
				
			||||||
    ;;
 | 
					    ;;
 | 
				
			||||||
 | 
					  l)
 | 
				
			||||||
 | 
					    ip_address_arg=-l
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
  p)
 | 
					  p)
 | 
				
			||||||
    public_ip="$OPTARG"
 | 
					    ip_address_arg=-p
 | 
				
			||||||
    ;;
 | 
					    ;;
 | 
				
			||||||
  n)
 | 
					  n)
 | 
				
			||||||
    num_tokens="$OPTARG"
 | 
					    num_tokens="$OPTARG"
 | 
				
			||||||
    ;;
 | 
					    ;;
 | 
				
			||||||
  P)
 | 
					 | 
				
			||||||
    public_ip="$(curl -s ifconfig.co)"
 | 
					 | 
				
			||||||
    echo "Public IP autodetected as $public_ip"
 | 
					 | 
				
			||||||
    ;;
 | 
					 | 
				
			||||||
  esac
 | 
					  esac
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [[ -n "$public_ip" ]]; then
 | 
					leader_address_args=("$ip_address_arg")
 | 
				
			||||||
  leader_address_args=(-b "$public_ip":8000)
 | 
					validator_address_args=("$ip_address_arg" -b 9000)
 | 
				
			||||||
  validator_address_args=(-b "$public_ip":9000)
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
  leader_address_args=(-d)
 | 
					 | 
				
			||||||
  validator_address_args=(-d -b 9000)
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
set -e
 | 
					set -e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								snap/hooks/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								snap/hooks/configure
									
									
									
									
										vendored
									
									
								
							@@ -10,9 +10,9 @@ if [[ -z "$mode" ]]; then
 | 
				
			|||||||
  exit 0
 | 
					  exit 0
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ip_address_arg=-p # Use public IP address (TODO: make this configurable?)
 | 
				
			||||||
num_tokens="$(snapctl get num-tokens)"
 | 
					num_tokens="$(snapctl get num-tokens)"
 | 
				
			||||||
public_ip="$(snapctl get public-ip)"
 | 
					$SNAP/bin/setup.sh ${num_tokens:+-n $num_tokens} ${ip_address_arg}
 | 
				
			||||||
$SNAP/bin/setup.sh ${num_tokens:+-n $num_tokens} ${public_ip:+-p $public_ip}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
case $mode in
 | 
					case $mode in
 | 
				
			||||||
leader+drone)
 | 
					leader+drone)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ extern crate solana;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use getopts::Options;
 | 
					use getopts::Options;
 | 
				
			||||||
use solana::crdt::{get_ip_addr, parse_port_or_addr, ReplicatedData};
 | 
					use solana::crdt::{get_ip_addr, parse_port_or_addr, ReplicatedData};
 | 
				
			||||||
 | 
					use solana::nat::get_public_ip_addr;
 | 
				
			||||||
use std::env;
 | 
					use std::env;
 | 
				
			||||||
use std::io;
 | 
					use std::io;
 | 
				
			||||||
use std::net::SocketAddr;
 | 
					use std::net::SocketAddr;
 | 
				
			||||||
@@ -19,7 +20,16 @@ fn print_usage(program: &str, opts: Options) {
 | 
				
			|||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    let mut opts = Options::new();
 | 
					    let mut opts = Options::new();
 | 
				
			||||||
    opts.optopt("b", "", "bind", "bind to port or address");
 | 
					    opts.optopt("b", "", "bind", "bind to port or address");
 | 
				
			||||||
    opts.optflag("d", "dyn", "detect network address dynamically");
 | 
					    opts.optflag(
 | 
				
			||||||
 | 
					        "p",
 | 
				
			||||||
 | 
					        "",
 | 
				
			||||||
 | 
					        "detect public network address using public servers",
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    opts.optflag(
 | 
				
			||||||
 | 
					        "l",
 | 
				
			||||||
 | 
					        "",
 | 
				
			||||||
 | 
					        "detect network address from local machine configuration",
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    opts.optflag("h", "help", "print help");
 | 
					    opts.optflag("h", "help", "print help");
 | 
				
			||||||
    let args: Vec<String> = env::args().collect();
 | 
					    let args: Vec<String> = env::args().collect();
 | 
				
			||||||
    let matches = match opts.parse(&args[1..]) {
 | 
					    let matches = match opts.parse(&args[1..]) {
 | 
				
			||||||
@@ -37,10 +47,14 @@ fn main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let bind_addr: SocketAddr = {
 | 
					    let bind_addr: SocketAddr = {
 | 
				
			||||||
        let mut bind_addr = parse_port_or_addr(matches.opt_str("b"));
 | 
					        let mut bind_addr = parse_port_or_addr(matches.opt_str("b"));
 | 
				
			||||||
        if matches.opt_present("d") {
 | 
					        if matches.opt_present("l") {
 | 
				
			||||||
            let ip = get_ip_addr().unwrap();
 | 
					            let ip = get_ip_addr().unwrap();
 | 
				
			||||||
            bind_addr.set_ip(ip);
 | 
					            bind_addr.set_ip(ip);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if matches.opt_present("p") {
 | 
				
			||||||
 | 
					            let ip = get_public_ip_addr().unwrap();
 | 
				
			||||||
 | 
					            bind_addr.set_ip(ip);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        bind_addr
 | 
					        bind_addr
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								src/nat.rs
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/nat.rs
									
									
									
									
									
								
							@@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern crate futures;
 | 
					extern crate futures;
 | 
				
			||||||
extern crate p2p;
 | 
					extern crate p2p;
 | 
				
			||||||
 | 
					extern crate reqwest;
 | 
				
			||||||
extern crate tokio_core;
 | 
					extern crate tokio_core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
 | 
					use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
 | 
				
			||||||
@@ -9,6 +10,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
 | 
				
			|||||||
use self::futures::Future;
 | 
					use self::futures::Future;
 | 
				
			||||||
use self::p2p::UdpSocketExt;
 | 
					use self::p2p::UdpSocketExt;
 | 
				
			||||||
use std::env;
 | 
					use std::env;
 | 
				
			||||||
 | 
					use std::str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A data type representing a public Udp socket
 | 
					/// A data type representing a public Udp socket
 | 
				
			||||||
pub struct UdpSocketPair {
 | 
					pub struct UdpSocketPair {
 | 
				
			||||||
@@ -17,6 +19,19 @@ pub struct UdpSocketPair {
 | 
				
			|||||||
    pub sender: UdpSocket,   // Locally bound socket to send via public address
 | 
					    pub sender: UdpSocket,   // Locally bound socket to send via public address
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Tries to determine the public IP address of this machine
 | 
				
			||||||
 | 
					pub fn get_public_ip_addr() -> Result<IpAddr, String> {
 | 
				
			||||||
 | 
					    let body = reqwest::get("http://ifconfig.co/ip")
 | 
				
			||||||
 | 
					        .map_err(|err| err.to_string())?
 | 
				
			||||||
 | 
					        .text()
 | 
				
			||||||
 | 
					        .map_err(|err| err.to_string())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    match body.lines().next() {
 | 
				
			||||||
 | 
					        Some(ip) => Result::Ok(ip.parse().unwrap()),
 | 
				
			||||||
 | 
					        None => Result::Err("Empty response body".to_string()),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Binds a private Udp address to a public address using UPnP if possible
 | 
					/// Binds a private Udp address to a public address using UPnP if possible
 | 
				
			||||||
pub fn udp_public_bind(label: &str) -> UdpSocketPair {
 | 
					pub fn udp_public_bind(label: &str) -> UdpSocketPair {
 | 
				
			||||||
    let private_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
 | 
					    let private_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user