Am I Mullvad? Or am I Death, destroyer of worlds?
This commit is contained in:
parent
3e82ec53ee
commit
17a530eb81
38
api.go
38
api.go
|
@ -32,21 +32,25 @@ type IPDetails struct {
|
|||
}
|
||||
|
||||
type MullvadServer struct {
|
||||
Hostname string `json:"hostname"`
|
||||
CountryCode string `json:"country_code"`
|
||||
CountryName string `json:"country_name"`
|
||||
CityCode string `json:"city_code"`
|
||||
CityName string `json:"city_name"`
|
||||
Active bool `json:"active"`
|
||||
Owned bool `json:"owned"`
|
||||
Provider string `json:"provider"`
|
||||
Ipv4AddrIn string `json:"ipv4_addr_in"`
|
||||
Ipv6AddrIn string `json:"ipv6_addr_in"`
|
||||
NetworkPortSpeed int `json:"network_port_speed"`
|
||||
Type string `json:"type"`
|
||||
Pubkey string `json:"pubkey,omitempty"`
|
||||
MultihopPort int `json:"multihop_port,omitempty"`
|
||||
SocksName string `json:"socks_name,omitempty"`
|
||||
SSHFingerprintSHA256 string `json:"ssh_fingerprint_sha256,omitempty"`
|
||||
SSHFingerprintMD5 string `json:"ssh_fingerprint_md5,omitempty"`
|
||||
Hostname string `json:"hostname"`
|
||||
CountryCode string `json:"country_code"`
|
||||
CountryName string `json:"country_name"`
|
||||
CityCode string `json:"city_code"`
|
||||
CityName string `json:"city_name"`
|
||||
Active bool `json:"active"`
|
||||
Owned bool `json:"owned"`
|
||||
Provider string `json:"provider"`
|
||||
Ipv4AddrIn string `json:"ipv4_addr_in"`
|
||||
Ipv6AddrIn *string `json:"ipv6_addr_in"`
|
||||
NetworkPortSpeed int `json:"network_port_speed"`
|
||||
Stboot bool `json:"stboot"`
|
||||
Type string `json:"type"`
|
||||
StatusMessages []interface{} `json:"status_messages"`
|
||||
Pubkey string `json:"pubkey,omitempty"`
|
||||
MultihopPort int `json:"multihop_port,omitempty"`
|
||||
SocksName string `json:"socks_name,omitempty"`
|
||||
SocksPort int `json:"socks_port,omitempty"`
|
||||
Ipv4V2Ray *string `json:"ipv4_v2ray,omitempty"`
|
||||
SshFingerprintSha256 string `json:"ssh_fingerprint_sha256,omitempty"`
|
||||
SshFingerprintMd5 string `json:"ssh_fingerprint_md5,omitempty"`
|
||||
}
|
||||
|
|
44
check.go
44
check.go
|
@ -2,6 +2,7 @@ package mullsox
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -123,10 +124,41 @@ func checkIP(ctx context.Context, h *http.Client, ipv6 bool) (details *IPDetails
|
|||
|
||||
// AmIMullvad checks if you are currently connecting through a Mullvad relay.
|
||||
// Returns the mullvad server you are connected to if any, and any error that occured
|
||||
func AmIMullvad(ctx context.Context) (*MullvadServer, error) {
|
||||
// v4, v6, err := CheckIP(ctx, http.DefaultClient)
|
||||
// m
|
||||
// if err != nil {
|
||||
// }
|
||||
return nil, nil
|
||||
//
|
||||
//goland:noinspection GoNilness
|
||||
func AmIMullvad(ctx context.Context, client *http.Client) (MullvadServer, error) {
|
||||
me, err := CheckIP(ctx, client)
|
||||
if me == nil || me.V4 == nil && me.V6 == nil {
|
||||
return MullvadServer{}, err
|
||||
}
|
||||
if me.V4 != nil && !me.V4.MullvadExitIP {
|
||||
return MullvadServer{}, err
|
||||
}
|
||||
if me.V6 != nil && !me.V6.MullvadExitIP {
|
||||
return MullvadServer{}, err
|
||||
}
|
||||
|
||||
relays, err := GetMullvadServers()
|
||||
if err != nil {
|
||||
return MullvadServer{}, err
|
||||
}
|
||||
|
||||
isMullvad := false
|
||||
if me.V4 != nil && me.V4.MullvadExitIP {
|
||||
isMullvad = true
|
||||
if relays.Has(me.V4.MullvadExitIPHostname) {
|
||||
return relays.Get(me.V4.MullvadExitIPHostname), nil
|
||||
}
|
||||
}
|
||||
if me.V6 != nil && me.V6.MullvadExitIP {
|
||||
isMullvad = true
|
||||
if relays.Has(me.V6.MullvadExitIPHostname) {
|
||||
return relays.Get(me.V6.MullvadExitIPHostname), nil
|
||||
}
|
||||
}
|
||||
if isMullvad {
|
||||
return MullvadServer{},
|
||||
errors.New("could not find mullvad server in relay list, but you are connected to a mullvad exit ip")
|
||||
}
|
||||
return MullvadServer{}, nil
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
func TestCheckIP4(t *testing.T) {
|
||||
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
v4, err := CheckIP4(ctx, http.DefaultClient)
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
|
@ -20,10 +20,11 @@ func TestCheckIP4(t *testing.T) {
|
|||
t.Fatalf("%s", err4j.Error())
|
||||
}
|
||||
t.Logf(string(v4j))
|
||||
cancel()
|
||||
}
|
||||
|
||||
func TestCheckIP6(t *testing.T) {
|
||||
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
v6, err := CheckIP6(ctx, http.DefaultClient)
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
|
@ -33,10 +34,11 @@ func TestCheckIP6(t *testing.T) {
|
|||
t.Fatalf("%s", err6j.Error())
|
||||
}
|
||||
t.Logf(string(v6j))
|
||||
cancel()
|
||||
}
|
||||
|
||||
func TestCheckIPConcurrent(t *testing.T) {
|
||||
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
me, err := CheckIP(ctx, http.DefaultClient)
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
|
@ -53,15 +55,30 @@ func TestCheckIPConcurrent(t *testing.T) {
|
|||
unv4 := &IPDetails{}
|
||||
unv6 := &IPDetails{}
|
||||
|
||||
if err := json.Unmarshal(v4j, unv4); err != nil {
|
||||
if err = json.Unmarshal(v4j, unv4); err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
}
|
||||
if err := json.Unmarshal(v6j, unv6); err != nil {
|
||||
if err = json.Unmarshal(v6j, unv6); err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
}
|
||||
unmarshaled.V4 = unv4
|
||||
unmarshaled.V6 = unv6
|
||||
|
||||
|
||||
t.Logf(spew.Sdump(unmarshaled.V4))
|
||||
t.Logf(spew.Sdump(unmarshaled.V6))
|
||||
cancel()
|
||||
}
|
||||
|
||||
func TestAmIMullvad(t *testing.T) {
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
|
||||
am, err := AmIMullvad(ctx, http.DefaultClient)
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
}
|
||||
indented, err := json.MarshalIndent(am, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err.Error())
|
||||
}
|
||||
t.Logf(string(indented))
|
||||
cancel()
|
||||
}
|
||||
|
|
51
relays.go
51
relays.go
|
@ -2,9 +2,9 @@ package mullsox
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
// "github.com/json-iterator/go"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -14,14 +14,52 @@ func (mvs MullvadServer) String() string {
|
|||
return mvs.Hostname
|
||||
}
|
||||
|
||||
type Relays []MullvadServer
|
||||
type Relays struct {
|
||||
m map[string]MullvadServer
|
||||
size int
|
||||
*sync.RWMutex
|
||||
}
|
||||
|
||||
func NewRelays() *Relays {
|
||||
r := &Relays{
|
||||
m: make(map[string]MullvadServer),
|
||||
RWMutex: &sync.RWMutex{},
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Relays) Slice() []MullvadServer {
|
||||
return *r
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
var servers []MullvadServer
|
||||
for _, server := range r.m {
|
||||
servers = append(servers, server)
|
||||
}
|
||||
return servers
|
||||
}
|
||||
|
||||
func (r *Relays) Has(hostname string) bool {
|
||||
r.RLock()
|
||||
_, ok := r.m[hostname]
|
||||
r.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
func (r *Relays) Add(server MullvadServer) {
|
||||
r.Lock()
|
||||
r.m[server.Hostname] = server
|
||||
r.Unlock()
|
||||
}
|
||||
|
||||
func (r *Relays) Get(hostname string) MullvadServer {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.m[hostname]
|
||||
}
|
||||
|
||||
func GetMullvadServers() (*Relays, error) {
|
||||
var servers = new(Relays)
|
||||
var servers = NewRelays()
|
||||
var serverSlice []MullvadServer
|
||||
req := fasthttp.AcquireRequest()
|
||||
res := fasthttp.AcquireResponse()
|
||||
defer func() {
|
||||
|
@ -35,8 +73,11 @@ func GetMullvadServers() (*Relays, error) {
|
|||
if err := fasthttp.Do(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(res.Body(), servers); err != nil {
|
||||
if err := json.Unmarshal(res.Body(), &serverSlice); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, server := range serverSlice {
|
||||
servers.Add(server)
|
||||
}
|
||||
return servers, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue