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"
futures = "0.1.21"
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
```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

View File

@ -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
-n num_tokens - Number of tokens to create
-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

View File

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

View File

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

View File

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