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"
 | 
			
		||||
futures = "0.1.21"
 | 
			
		||||
clap = "2.31"
 | 
			
		||||
reqwest = "0.8.6"
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,7 @@ Runtime configuration files for the daemon can be found in
 | 
			
		||||
 | 
			
		||||
#### Leader daemon
 | 
			
		||||
```bash
 | 
			
		||||
$ sudo snap set solana mode=leader public-ip=$(curl -s http://ifconfig.co)
 | 
			
		||||
$ sudo snap set solana mode=leader
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
```bash
 | 
			
		||||
$ sudo snap set solana mode=leader+drone public-ip=$(curl -s http://ifconfig.co)
 | 
			
		||||
$ sudo snap set solana mode=leader+drone
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Validator daemon
 | 
			
		||||
```bash
 | 
			
		||||
$ sudo snap set solana mode=validator public-ip=$(curl -s http://ifconfig.co)
 | 
			
		||||
$ sudo snap set solana mode=validator
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
If CUDA is available:
 | 
			
		||||
```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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,53 +1,45 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
num_tokens=1000000000
 | 
			
		||||
public_ip=
 | 
			
		||||
 | 
			
		||||
here=$(dirname "$0")
 | 
			
		||||
# shellcheck source=multinode-demo/common.sh
 | 
			
		||||
source "$here"/common.sh
 | 
			
		||||
 | 
			
		||||
usage () {
 | 
			
		||||
  cat <<EOF
 | 
			
		||||
usage: $0 [-n num_tokens] [-P] [-p public_ip_address]
 | 
			
		||||
usage: $0 [-n num_tokens] [-l] [-p]
 | 
			
		||||
 | 
			
		||||
Creates a fullnode configuration
 | 
			
		||||
 | 
			
		||||
 -n num_tokens  - Number of tokens to create
 | 
			
		||||
 -p public_ip_address  - Public IP address to advertise
 | 
			
		||||
                         (default uses the system IP address, which may be
 | 
			
		||||
                          on a private network)
 | 
			
		||||
 -P                    - Autodetect the public IP address of the machine
 | 
			
		||||
 -l             - Detect network address from local machine configuration, which
 | 
			
		||||
                  may be a private IP address unaccessible on the Intenet (default)
 | 
			
		||||
 -p             - Detect public address using public Internet servers
 | 
			
		||||
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
 | 
			
		||||
  h|\?)
 | 
			
		||||
    usage
 | 
			
		||||
    exit 0
 | 
			
		||||
    ;;
 | 
			
		||||
  l)
 | 
			
		||||
    ip_address_arg=-l
 | 
			
		||||
    ;;
 | 
			
		||||
  p)
 | 
			
		||||
    public_ip="$OPTARG"
 | 
			
		||||
    ip_address_arg=-p
 | 
			
		||||
    ;;
 | 
			
		||||
  n)
 | 
			
		||||
    num_tokens="$OPTARG"
 | 
			
		||||
    ;;
 | 
			
		||||
  P)
 | 
			
		||||
    public_ip="$(curl -s ifconfig.co)"
 | 
			
		||||
    echo "Public IP autodetected as $public_ip"
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if [[ -n "$public_ip" ]]; then
 | 
			
		||||
  leader_address_args=(-b "$public_ip":8000)
 | 
			
		||||
  validator_address_args=(-b "$public_ip":9000)
 | 
			
		||||
else
 | 
			
		||||
  leader_address_args=(-d)
 | 
			
		||||
  validator_address_args=(-d -b 9000)
 | 
			
		||||
fi
 | 
			
		||||
leader_address_args=("$ip_address_arg")
 | 
			
		||||
validator_address_args=("$ip_address_arg" -b 9000)
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								snap/hooks/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								snap/hooks/configure
									
									
									
									
										vendored
									
									
								
							@@ -10,9 +10,9 @@ if [[ -z "$mode" ]]; then
 | 
			
		||||
  exit 0
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
ip_address_arg=-p # Use public IP address (TODO: make this configurable?)
 | 
			
		||||
num_tokens="$(snapctl get num-tokens)"
 | 
			
		||||
public_ip="$(snapctl get public-ip)"
 | 
			
		||||
$SNAP/bin/setup.sh ${num_tokens:+-n $num_tokens} ${public_ip:+-p $public_ip}
 | 
			
		||||
$SNAP/bin/setup.sh ${num_tokens:+-n $num_tokens} ${ip_address_arg}
 | 
			
		||||
 | 
			
		||||
case $mode in
 | 
			
		||||
leader+drone)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ extern crate solana;
 | 
			
		||||
 | 
			
		||||
use getopts::Options;
 | 
			
		||||
use solana::crdt::{get_ip_addr, parse_port_or_addr, ReplicatedData};
 | 
			
		||||
use solana::nat::get_public_ip_addr;
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::net::SocketAddr;
 | 
			
		||||
@@ -19,7 +20,16 @@ fn print_usage(program: &str, opts: Options) {
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut opts = Options::new();
 | 
			
		||||
    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");
 | 
			
		||||
    let args: Vec<String> = env::args().collect();
 | 
			
		||||
    let matches = match opts.parse(&args[1..]) {
 | 
			
		||||
@@ -37,10 +47,14 @@ fn main() {
 | 
			
		||||
 | 
			
		||||
    let bind_addr: SocketAddr = {
 | 
			
		||||
        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();
 | 
			
		||||
            bind_addr.set_ip(ip);
 | 
			
		||||
        }
 | 
			
		||||
        if matches.opt_present("p") {
 | 
			
		||||
            let ip = get_public_ip_addr().unwrap();
 | 
			
		||||
            bind_addr.set_ip(ip);
 | 
			
		||||
        }
 | 
			
		||||
        bind_addr
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								src/nat.rs
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/nat.rs
									
									
									
									
									
								
							@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
extern crate futures;
 | 
			
		||||
extern crate p2p;
 | 
			
		||||
extern crate reqwest;
 | 
			
		||||
extern crate tokio_core;
 | 
			
		||||
 | 
			
		||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
 | 
			
		||||
@@ -9,6 +10,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
 | 
			
		||||
use self::futures::Future;
 | 
			
		||||
use self::p2p::UdpSocketExt;
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::str;
 | 
			
		||||
 | 
			
		||||
/// A data type representing a public Udp socket
 | 
			
		||||
pub struct UdpSocketPair {
 | 
			
		||||
@@ -17,6 +19,19 @@ pub struct UdpSocketPair {
 | 
			
		||||
    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
 | 
			
		||||
pub fn udp_public_bind(label: &str) -> UdpSocketPair {
 | 
			
		||||
    let private_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user