Skip to content

Commit

Permalink
Add IPv6 mode
Browse files Browse the repository at this point in the history
- Add IPv4, IPv6 flag to all targets
- Clean all arguments and options with docopt
  • Loading branch information
kitsuyui committed Feb 21, 2018
1 parent 8beb77c commit 1d6ac82
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 92 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,39 @@ $ myip -v
203.0.113.2
```

## Ready for IPv6

When your machine has IPv6 address, `-6` option is available.

```console
$ myip -6
2001:0db8:0000:0042:0000:8a2e:0370:7334
```

If your machine doesn't have IPv6 address, fallbacks to IPv4.

## Help

```
$ myip -h
myip
Usage:
myip [-v | --verbose] [-4 | -6] [-T=<rate>] [-t=<duration>]
myip (--help | --version)
Options:
-h --help Show this screen.
-V --version Show version.
-v --verbose Verbose mode.
-4 --ipv4 Prefer IPv4.
-6 --ipv6 Prefer IPv6.
-n --newline Show IP with newline.
-N --no-newline Show IP without newline.
-T=<rate> --threshold=<rate> Threshold that must be exceeded by weighted votes [default: 0.5].
-t=<duration> --timeout=<duration> Timeout [default: 3s].
```

# Installation

## go get
Expand Down Expand Up @@ -115,3 +148,4 @@ The 3-Clause BSD License. See also LISENCE file.
- [golang/go](https://github.com/golang/go/) ... [BSD 3-Clause "New" or "Revised" License](https://github.com/golang/go/blob/master/LICENSE)
- [miekg/dns](https://github.com/miekg/dns) ... [BSD 3-Clause "New" or "Revised" License](https://github.com/miekg/dns/blob/master/LICENSE)
- [gortc/stun](https://github.com/gortc/stun) ... [BSD 3-Clause "New" or "Revised" License](https://github.com/gortc/stun/blob/master/LICENSE)
- [docopt/docopt-go](https://github.com/docopt/docopt.go) ... [MIT License](https://github.com/docopt/docopt.go/blob/master/LICENSE)
2 changes: 2 additions & 0 deletions base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type IPRetrievable interface {
type ScoredIPRetrievable struct {
IPRetrievable
Weight float64
IPv4 bool
IPv6 bool
}

func (p ScoredIPRetrievable) RetriveIPWithScoring(ctx context.Context) (*ScoredIP, error) {
Expand Down
84 changes: 65 additions & 19 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package main
import (
"context"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"time"

"github.com/docopt/docopt-go"
"github.com/kitsuyui/myip/base"
"github.com/kitsuyui/myip/dns_resolver"
"github.com/kitsuyui/myip/http_resolver"
Expand All @@ -16,6 +19,7 @@ import (
)

var version string
var verboseMode bool

func typeName(ipr interface{}) string {
switch ipr.(type) {
Expand All @@ -36,7 +40,7 @@ func pickUpFirstItemThatExceededThreshold(siprs []base.ScoredIPRetrievable, time
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
logger := log.Logger{}
if *verboseMode {
if verboseMode {
logger.SetOutput(os.Stderr)
} else {
logger.SetOutput(ioutil.Discard)
Expand Down Expand Up @@ -71,33 +75,75 @@ func pickUpFirstItemThatExceededThreshold(siprs []base.ScoredIPRetrievable, time
return &sip, nil
}

var useNewline = flag.Bool("newline", false, "Show IP with newline.")
var cmdVersion = flag.Bool("version", false, "Show version.")
var verboseMode = flag.Bool("verbose", false, "Verbose mode.")
var timeout = flag.Duration("timeout", 3*time.Second, "Timeout duration.")
var scoreThreshold = flag.Float64("threshold", 0.5, "Threshold that should be exceeded by top weighted votes.")

func init() {
flag.BoolVar(useNewline, "n", false, "Show IP with newline.")
flag.BoolVar(cmdVersion, "V", false, "Show version.")
flag.BoolVar(verboseMode, "v", false, "Verbose mode.")
flag.DurationVar(timeout, "t", 1*time.Second, "Timeout duration.")
flag.Float64Var(scoreThreshold, "T", 0.5, "Threshold that should be exceeded by top weighted votes.")
flag.DurationVar(timeout, "t", 3*time.Second, "Timeout duration.")
}

func main() {
flag.Parse()
if *cmdVersion {

usage := `myip
Usage:
myip [-v | --verbose] [-4 | -6] [-T=<rate>] [-t=<duration>]
myip (--help | --version)
Options:
-h --help Show this screen.
-V --version Show version.
-v --verbose Verbose mode.
-4 --ipv4 Prefer IPv4.
-6 --ipv6 Prefer IPv6.
-n --newline Show IP with newline.
-N --no-newline Show IP without newline.
-T=<rate> --threshold=<rate> Threshold that must be exceeded by weighted votes [default: 0.5].
-t=<duration> --timeout=<duration> Timeout [default: 3s].
`
opts, err := docopt.ParseDoc(usage)
if err != nil {
fmt.Errorf("%s", err)
}
if showVersion, _ := opts.Bool("--version"); showVersion {
println(version)
return
}
sir := targets.IPRetrievables()
sip, err := pickUpFirstItemThatExceededThreshold(sir, *timeout, *scoreThreshold)
if err == nil && sip.Score >= *scoreThreshold {
if *useNewline {
println(sip.IP.String())
} else {
print(sip.IP.String())
var sir []base.ScoredIPRetrievable
if ipv4, _ := opts.Bool("--ipv4"); ipv4 {
sir = targets.IPv4Retrievables()
} else if ipv6, _ := opts.Bool("--ipv6"); ipv6 {
sir = targets.IPv6Retrievables()
} else {
sir = targets.IPRetrievables()
}
if verbose, _ := opts.Bool("--verbose"); verbose {
verboseMode = true
}
threshold, err := opts.Float64("--threshold")
if err != nil {
fmt.Errorf("%s", err)
}

timeoutStr, err := opts.String("--timeout")
if err != nil {
fmt.Errorf("%s", err)
}

var duration time.Duration
f, err := strconv.ParseFloat(timeoutStr, 64)
if err != nil {
duration, err = time.ParseDuration(timeoutStr)
if err != nil {
fmt.Errorf("%s", err)
}
} else {
duration = time.Duration(f) * time.Second
}
sip, err := pickUpFirstItemThatExceededThreshold(sir, duration, threshold)
if err == nil && sip.Score >= threshold {
print(sip.IP.String())
if newline, _ := opts.Bool("--newline"); newline {
println("")
}
} else {
os.Exit(1)
Expand Down
Loading

0 comments on commit 1d6ac82

Please sign in to comment.