Move public IP address detection out of bash

This commit is contained in:
Michael Vines 2018-06-29 16:49:23 -07:00 committed by Grimes
parent a31889f129
commit 450f271cf7
6 changed files with 52 additions and 30 deletions

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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)

View File

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

View File

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