Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move public IP address detection out of bash #499

Merged
merged 1 commit into from
Jun 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ bs58 = "0.2.0"
p2p = "0.5.2"
futures = "0.1.21"
clap = "2.31"
reqwest = "0.8.6"
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
36 changes: 14 additions & 22 deletions multinode-demo/setup.sh
Original file line number Diff line number Diff line change
@@ -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

Expand Down
4 changes: 2 additions & 2 deletions snap/hooks/configure
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions src/bin/fullnode-config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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..]) {
Expand All @@ -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
};

Expand Down
15 changes: 15 additions & 0 deletions src/nat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

extern crate futures;
extern crate p2p;
extern crate reqwest;
extern crate tokio_core;

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 {
Expand All @@ -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);
Expand Down