Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
gost
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
gost
Commits
822cc6ac
Commit
822cc6ac
authored
Jul 18, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
9884015d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
164 additions
and
369 deletions
+164
-369
handler.go
handler.go
+26
-0
options.go
options.go
+11
-3
ss.go
ss.go
+92
-159
ssocks/ssocks.go
ssocks/ssocks.go
+0
-165
tcp/client.go
tcp/client.go
+12
-9
tcp/options.go
tcp/options.go
+4
-15
tcp/server.go
tcp/server.go
+19
-18
No files found.
handler.go
0 → 100644
View file @
822cc6ac
package
gost
import
(
"net"
)
type
Handler
interface
{
Handle
(
net
.
Conn
)
}
type
DefaultHandler
struct
{
server
Server
}
func
(
h
*
DefaultHandler
)
Handle
(
conn
net
.
Conn
)
{
var
handler
Handler
switch
h
.
server
.
Options
()
.
BaseOptions
()
.
Protocol
{
case
"http"
:
case
"ss"
:
// shadowsocks
handler
=
ShadowHandler
(
h
.
server
)
}
handler
.
Handle
(
conn
)
}
options.go
View file @
822cc6ac
...
...
@@ -2,6 +2,7 @@ package gost
import
(
"log"
"net/url"
"reflect"
)
...
...
@@ -13,9 +14,10 @@ type Options interface {
type
Option
func
(
Options
)
type
BaseOptions
struct
{
Addr
string
`opt:"addr"`
// [host]:port
Protocol
string
`opt:"protocol"`
// protocol: http/socks5/ss
Transport
string
`opt:"transport"`
// transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp
Addr
string
`opt:"addr"`
// [host]:port
Protocol
string
`opt:"protocol"`
// protocol: http/socks5/ss
Transport
string
`opt:"transport"`
// transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp
Users
[]
url
.
Userinfo
`opt:"users"`
// authentication for proxy
}
func
AddrOption
(
a
string
)
Option
{
...
...
@@ -36,6 +38,12 @@ func TransportOption(t string) Option {
}
}
func
UsersOption
(
users
...
url
.
Userinfo
)
Option
{
return
func
(
opts
Options
)
{
opts
.
BaseOptions
()
.
Users
=
users
}
}
func
GetOption
(
i
interface
{},
opt
string
)
interface
{}
{
ps
:=
reflect
.
ValueOf
(
i
)
if
ps
.
Kind
()
!=
reflect
.
Ptr
&&
ps
.
Kind
()
!=
reflect
.
Interface
{
...
...
ss.go
View file @
822cc6ac
...
...
@@ -3,7 +3,6 @@ package gost
import
(
"bytes"
"encoding/binary"
"errors"
"fmt"
"io"
"net"
...
...
@@ -11,72 +10,126 @@ import (
"time"
"github.com/ginuerzh/gosocks5"
"github.com/go-log/log"
"github.com/golang/glog"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
)
const
(
idType
=
0
// address type index
idIP0
=
1
// ip addres start index
idDmLen
=
1
// domain address length index
idDm0
=
2
// domain address start index
// Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write,
// we wrap around it to make io.Copy happy
type
shadowConn
struct
{
conn
net
.
Conn
}
typeIPv4
=
1
// type is ipv4 address
typeDm
=
3
// type is domain address
typeIPv6
=
4
// type is ipv6 address
func
ShadowConn
(
conn
net
.
Conn
)
net
.
Conn
{
return
&
shadowConn
{
conn
:
conn
}
}
lenIPv4
=
net
.
IPv4len
+
2
// ipv4 + 2port
lenIPv6
=
net
.
IPv6len
+
2
// ipv6 + 2port
lenDmBase
=
2
// 1addrLen + 2port, plus addrLen
lenHmacSha1
=
10
)
func
(
c
*
shadowConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
conn
.
Read
(
b
)
}
type
ShadowServer
struct
{
conn
*
ss
.
Conn
Base
*
ProxyServer
OTA
bool
// one time auth
func
(
c
*
shadowConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
n
=
len
(
b
)
// force byte length consistent
_
,
err
=
c
.
conn
.
Write
(
b
)
return
}
func
(
c
*
shadowConn
)
Close
()
error
{
return
c
.
conn
.
Close
()
}
func
(
c
*
shadowConn
)
LocalAddr
()
net
.
Addr
{
return
c
.
conn
.
LocalAddr
()
}
func
(
c
*
shadowConn
)
RemoteAddr
()
net
.
Addr
{
return
c
.
conn
.
RemoteAddr
()
}
func
(
c
*
shadowConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetDeadline
(
t
)
}
func
(
c
*
shadowConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetReadDeadline
(
t
)
}
func
(
c
*
shadowConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetWriteDeadline
(
t
)
}
func
NewShadowServer
(
conn
*
ss
.
Conn
,
base
*
ProxyServer
)
*
ShadowServer
{
return
&
ShadowServer
{
conn
:
conn
,
Base
:
base
}
type
shadowHandler
struct
{
server
Server
}
func
(
s
*
ShadowServer
)
Serve
()
{
glog
.
V
(
LINFO
)
.
Infof
(
"[ss] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
s
.
conn
.
LocalAddr
())
func
ShadowHandler
(
server
Server
)
Handler
{
return
&
shadowHandler
{
server
:
server
}
}
func
(
h
*
shadowHandler
)
Handle
(
conn
net
.
Conn
)
{
var
method
,
password
string
users
:=
h
.
server
.
Options
()
.
BaseOptions
()
.
Users
if
len
(
users
)
>
0
{
method
=
users
[
0
]
.
Username
()
password
,
_
=
users
[
0
]
.
Password
()
}
cipher
,
err
:=
ss
.
NewCipher
(
method
,
password
)
if
err
!=
nil
{
log
.
Log
(
"[ss]"
,
err
)
return
}
conn
=
ShadowConn
(
ss
.
NewConn
(
conn
,
cipher
))
log
.
Logf
(
"[ss] %s - %s"
,
conn
.
RemoteAddr
(),
conn
.
LocalAddr
())
addr
,
ota
,
err
:=
s
.
getRequest
(
)
addr
,
err
:=
h
.
getRequest
(
conn
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[ss] %s - %s : %s"
,
s
.
conn
.
RemoteAddr
(),
s
.
conn
.
LocalAddr
(),
err
)
log
.
Logf
(
"[ss] %s - %s : %s"
,
conn
.
RemoteAddr
(),
conn
.
LocalAddr
(),
err
)
return
}
glog
.
V
(
LINFO
)
.
Infof
(
"[ss] %s -> %s, ota: %v"
,
s
.
conn
.
RemoteAddr
(),
addr
,
ota
)
log
.
Logf
(
"[ss] %s -> %s"
,
conn
.
RemoteAddr
(),
addr
)
cc
,
err
:=
s
.
Base
.
Chain
.
Dial
(
addr
)
cc
,
err
:=
h
.
server
.
Chain
()
.
Dial
(
addr
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[ss] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
addr
,
err
)
log
.
Logf
(
"[ss] %s -> %s : %s"
,
conn
.
RemoteAddr
(),
addr
,
err
)
return
}
defer
cc
.
Close
()
glog
.
V
(
LINFO
)
.
Infof
(
"[ss] %s <-> %s"
,
s
.
conn
.
RemoteAddr
(),
addr
)
if
ota
{
s
.
transportOTA
(
s
.
conn
,
cc
)
}
else
{
s
.
Base
.
transport
(
&
shadowConn
{
conn
:
s
.
conn
},
cc
)
}
glog
.
V
(
LINFO
)
.
Infof
(
"[ss] %s >-< %s"
,
s
.
conn
.
RemoteAddr
(),
addr
)
log
.
Logf
(
"[ss] %s <-> %s"
,
conn
.
RemoteAddr
(),
addr
)
defer
log
.
Logf
(
"[ss] %s >-< %s"
,
conn
.
RemoteAddr
(),
addr
)
Transport
(
conn
,
cc
)
}
const
(
idType
=
0
// address type index
idIP0
=
1
// ip addres start index
idDmLen
=
1
// domain address length index
idDm0
=
2
// domain address start index
typeIPv4
=
1
// type is ipv4 address
typeDm
=
3
// type is domain address
typeIPv6
=
4
// type is ipv6 address
lenIPv4
=
net
.
IPv4len
+
2
// ipv4 + 2port
lenIPv6
=
net
.
IPv6len
+
2
// ipv6 + 2port
lenDmBase
=
2
// 1addrLen + 2port, plus addrLen
lenHmacSha1
=
10
)
// This function is copied from shadowsocks library with some modification.
func
(
s
*
ShadowServer
)
getRequest
()
(
host
string
,
ota
bool
,
err
error
)
{
func
(
h
*
shadowHandler
)
getRequest
(
conn
net
.
Conn
)
(
host
string
,
err
error
)
{
// buf size should at least have the same size with the largest possible
// request size (when addrType is 3, domain name has at most 256 bytes)
// 1(addrType) + 1(lenByte) + 256(max length address) + 2(port)
buf
:=
make
([]
byte
,
SmallBufferSize
)
// read till we get possible domain length field
s
.
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
:
idType
+
1
]);
err
!=
nil
{
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
30
*
time
.
Second
))
if
_
,
err
=
io
.
ReadFull
(
conn
,
buf
[
:
idType
+
1
]);
err
!=
nil
{
return
}
...
...
@@ -88,7 +141,7 @@ func (s *ShadowServer) getRequest() (host string, ota bool, err error) {
case
typeIPv6
:
reqStart
,
reqEnd
=
idIP0
,
idIP0
+
lenIPv6
case
typeDm
:
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
idType
+
1
:
idDmLen
+
1
]);
err
!=
nil
{
if
_
,
err
=
io
.
ReadFull
(
conn
,
buf
[
idType
+
1
:
idDmLen
+
1
]);
err
!=
nil
{
return
}
reqStart
,
reqEnd
=
idDm0
,
int
(
idDm0
+
buf
[
idDmLen
]
+
lenDmBase
)
...
...
@@ -97,7 +150,7 @@ func (s *ShadowServer) getRequest() (host string, ota bool, err error) {
return
}
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
reqStart
:
reqEnd
]);
err
!=
nil
{
if
_
,
err
=
io
.
ReadFull
(
conn
,
buf
[
reqStart
:
reqEnd
]);
err
!=
nil
{
return
}
...
...
@@ -115,129 +168,9 @@ func (s *ShadowServer) getRequest() (host string, ota bool, err error) {
// parse port
port
:=
binary
.
BigEndian
.
Uint16
(
buf
[
reqEnd
-
2
:
reqEnd
])
host
=
net
.
JoinHostPort
(
host
,
strconv
.
Itoa
(
int
(
port
)))
// if specified one time auth enabled, we should verify this
if
s
.
OTA
||
addrType
&
ss
.
OneTimeAuthMask
>
0
{
ota
=
true
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
reqEnd
:
reqEnd
+
lenHmacSha1
]);
err
!=
nil
{
return
}
iv
:=
s
.
conn
.
GetIv
()
key
:=
s
.
conn
.
GetKey
()
actualHmacSha1Buf
:=
ss
.
HmacSha1
(
append
(
iv
,
key
...
),
buf
[
:
reqEnd
])
if
!
bytes
.
Equal
(
buf
[
reqEnd
:
reqEnd
+
lenHmacSha1
],
actualHmacSha1Buf
)
{
err
=
fmt
.
Errorf
(
"verify one time auth failed, iv=%v key=%v data=%v"
,
iv
,
key
,
buf
[
:
reqEnd
])
return
}
}
return
}
const
(
dataLenLen
=
2
hmacSha1Len
=
10
idxData0
=
dataLenLen
+
hmacSha1Len
)
// copyOta copies data from src to dst with ota verification.
//
// This function is copied from shadowsocks library with some modification.
func
(
s
*
ShadowServer
)
copyOta
(
dst
net
.
Conn
,
src
*
ss
.
Conn
)
(
int64
,
error
)
{
// sometimes it have to fill large block
buf
:=
make
([]
byte
,
LargeBufferSize
)
for
{
src
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
if
n
,
err
:=
io
.
ReadFull
(
src
,
buf
[
:
dataLenLen
+
hmacSha1Len
]);
err
!=
nil
{
return
int64
(
n
),
err
}
src
.
SetReadDeadline
(
time
.
Time
{})
dataLen
:=
binary
.
BigEndian
.
Uint16
(
buf
[
:
dataLenLen
])
expectedHmacSha1
:=
buf
[
dataLenLen
:
idxData0
]
var
dataBuf
[]
byte
if
len
(
buf
)
<
int
(
idxData0
+
dataLen
)
{
dataBuf
=
make
([]
byte
,
dataLen
)
}
else
{
dataBuf
=
buf
[
idxData0
:
idxData0
+
dataLen
]
}
if
n
,
err
:=
io
.
ReadFull
(
src
,
dataBuf
);
err
!=
nil
{
return
int64
(
n
),
err
}
chunkIdBytes
:=
make
([]
byte
,
4
)
chunkId
:=
src
.
GetAndIncrChunkId
()
binary
.
BigEndian
.
PutUint32
(
chunkIdBytes
,
chunkId
)
actualHmacSha1
:=
ss
.
HmacSha1
(
append
(
src
.
GetIv
(),
chunkIdBytes
...
),
dataBuf
)
if
!
bytes
.
Equal
(
expectedHmacSha1
,
actualHmacSha1
)
{
return
0
,
errors
.
New
(
"ota error: mismatch"
)
}
if
n
,
err
:=
dst
.
Write
(
dataBuf
);
err
!=
nil
{
return
int64
(
n
),
err
}
}
}
func
(
s
*
ShadowServer
)
transportOTA
(
sc
*
ss
.
Conn
,
cc
net
.
Conn
)
(
err
error
)
{
errc
:=
make
(
chan
error
,
2
)
go
func
()
{
_
,
err
:=
io
.
Copy
(
&
shadowConn
{
conn
:
sc
},
cc
)
errc
<-
err
}()
go
func
()
{
_
,
err
:=
s
.
copyOta
(
cc
,
sc
)
errc
<-
err
}()
select
{
case
err
=
<-
errc
:
//glog.V(LWARNING).Infoln("transport exit", err)
}
return
}
// Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write,
// we wrap around it to make io.Copy happy
type
shadowConn
struct
{
conn
*
ss
.
Conn
}
func
(
c
*
shadowConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
conn
.
Read
(
b
)
}
func
(
c
*
shadowConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
n
=
len
(
b
)
// force byte length consistent
_
,
err
=
c
.
conn
.
Write
(
b
)
return
}
func
(
c
*
shadowConn
)
Close
()
error
{
return
c
.
conn
.
Close
()
}
func
(
c
*
shadowConn
)
LocalAddr
()
net
.
Addr
{
return
c
.
conn
.
LocalAddr
()
}
func
(
c
*
shadowConn
)
RemoteAddr
()
net
.
Addr
{
return
c
.
conn
.
RemoteAddr
()
}
func
(
c
*
shadowConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetDeadline
(
t
)
}
func
(
c
*
shadowConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetReadDeadline
(
t
)
}
func
(
c
*
shadowConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetWriteDeadline
(
t
)
}
type
ShadowUdpServer
struct
{
Base
*
ProxyServer
TTL
int
...
...
ssocks/ssocks.go
deleted
100644 → 0
View file @
9884015d
package
ssocks
import
(
"encoding/binary"
"fmt"
"io"
"net"
"net/url"
"strconv"
"time"
"github.com/go-log/log"
"github.com/ginuerzh/gost"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
)
// Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write,
// we wrap around it to make io.Copy happy
type
shadowConn
struct
{
conn
net
.
Conn
}
func
NewConn
(
conn
net
.
Conn
)
net
.
Conn
{
return
&
shadowConn
{
conn
:
conn
}
}
func
(
c
*
shadowConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
conn
.
Read
(
b
)
}
func
(
c
*
shadowConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
n
=
len
(
b
)
// force byte length consistent
_
,
err
=
c
.
conn
.
Write
(
b
)
return
}
func
(
c
*
shadowConn
)
Close
()
error
{
return
c
.
conn
.
Close
()
}
func
(
c
*
shadowConn
)
LocalAddr
()
net
.
Addr
{
return
c
.
conn
.
LocalAddr
()
}
func
(
c
*
shadowConn
)
RemoteAddr
()
net
.
Addr
{
return
c
.
conn
.
RemoteAddr
()
}
func
(
c
*
shadowConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetDeadline
(
t
)
}
func
(
c
*
shadowConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetReadDeadline
(
t
)
}
func
(
c
*
shadowConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
c
.
conn
.
SetWriteDeadline
(
t
)
}
const
(
idType
=
0
// address type index
idIP0
=
1
// ip addres start index
idDmLen
=
1
// domain address length index
idDm0
=
2
// domain address start index
typeIPv4
=
1
// type is ipv4 address
typeDm
=
3
// type is domain address
typeIPv6
=
4
// type is ipv6 address
lenIPv4
=
net
.
IPv4len
+
2
// ipv4 + 2port
lenIPv6
=
net
.
IPv6len
+
2
// ipv6 + 2port
lenDmBase
=
2
// 1addrLen + 2port, plus addrLen
lenHmacSha1
=
10
)
type
ShadowServer
struct
{
conn
net
.
Conn
base
gost
.
Server
}
func
NewServer
(
conn
net
.
Conn
,
cipher
*
url
.
Userinfo
,
base
gost
.
Server
)
(
*
ShadowServer
,
error
)
{
method
:=
cipher
.
Username
()
password
,
_
:=
cipher
.
Password
()
cp
,
err
:=
ss
.
NewCipher
(
method
,
password
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
ShadowServer
{
conn
:
ss
.
NewConn
(
conn
,
cp
),
base
:
base
},
nil
}
func
(
s
*
ShadowServer
)
Serve
()
error
{
log
.
Logf
(
"[ss] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
s
.
conn
.
LocalAddr
())
addr
,
err
:=
s
.
getRequest
()
if
err
!=
nil
{
log
.
Logf
(
"[ss] %s - %s : %s"
,
s
.
conn
.
RemoteAddr
(),
s
.
conn
.
LocalAddr
(),
err
)
return
err
}
log
.
Logf
(
"[ss] %s -> %s"
,
s
.
conn
.
RemoteAddr
(),
addr
)
cc
,
err
:=
s
.
base
.
Chain
()
.
Dial
(
addr
)
if
err
!=
nil
{
log
.
Logf
(
"[ss] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
addr
,
err
)
return
err
}
defer
cc
.
Close
()
log
.
Logf
(
"[ss] %s <-> %s"
,
s
.
conn
.
RemoteAddr
(),
addr
)
defer
log
.
Logf
(
"[ss] %s >-< %s"
,
s
.
conn
.
RemoteAddr
(),
addr
)
return
gost
.
Transport
(
&
shadowConn
{
conn
:
s
.
conn
},
cc
)
}
// This function is copied from shadowsocks library with some modification.
func
(
s
*
ShadowServer
)
getRequest
()
(
host
string
,
err
error
)
{
// buf size should at least have the same size with the largest possible
// request size (when addrType is 3, domain name has at most 256 bytes)
// 1(addrType) + 1(lenByte) + 256(max length address) + 2(port)
buf
:=
make
([]
byte
,
gost
.
SmallBufferSize
)
// read till we get possible domain length field
s
.
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
30
*
time
.
Second
))
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
:
idType
+
1
]);
err
!=
nil
{
return
}
var
reqStart
,
reqEnd
int
addrType
:=
buf
[
idType
]
switch
addrType
&
ss
.
AddrMask
{
case
typeIPv4
:
reqStart
,
reqEnd
=
idIP0
,
idIP0
+
lenIPv4
case
typeIPv6
:
reqStart
,
reqEnd
=
idIP0
,
idIP0
+
lenIPv6
case
typeDm
:
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
idType
+
1
:
idDmLen
+
1
]);
err
!=
nil
{
return
}
reqStart
,
reqEnd
=
idDm0
,
int
(
idDm0
+
buf
[
idDmLen
]
+
lenDmBase
)
default
:
err
=
fmt
.
Errorf
(
"addr type %d not supported"
,
addrType
&
ss
.
AddrMask
)
return
}
if
_
,
err
=
io
.
ReadFull
(
s
.
conn
,
buf
[
reqStart
:
reqEnd
]);
err
!=
nil
{
return
}
// Return string for typeIP is not most efficient, but browsers (Chrome,
// Safari, Firefox) all seems using typeDm exclusively. So this is not a
// big problem.
switch
addrType
&
ss
.
AddrMask
{
case
typeIPv4
:
host
=
net
.
IP
(
buf
[
idIP0
:
idIP0
+
net
.
IPv4len
])
.
String
()
case
typeIPv6
:
host
=
net
.
IP
(
buf
[
idIP0
:
idIP0
+
net
.
IPv6len
])
.
String
()
case
typeDm
:
host
=
string
(
buf
[
idDm0
:
idDm0
+
buf
[
idDmLen
]])
}
// parse port
port
:=
binary
.
BigEndian
.
Uint16
(
buf
[
reqEnd
-
2
:
reqEnd
])
host
=
net
.
JoinHostPort
(
host
,
strconv
.
Itoa
(
int
(
port
)))
return
}
tcp/client.go
View file @
822cc6ac
...
...
@@ -14,8 +14,8 @@ import (
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gost"
"github.com/ginuerzh/gost/socks"
"github.com/ginuerzh/gost/ssocks"
"github.com/go-log/log"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
)
...
...
@@ -45,8 +45,9 @@ func (c *nodeClient) Dial(conn net.Conn, addr string) (net.Conn, error) {
gosocks5
.
MethodUserPass
,
socks
.
MethodTLS
,
)
if
len
(
c
.
options
.
users
)
>
0
{
selector
.
User
=
&
c
.
options
.
users
[
0
]
users
:=
c
.
options
.
BaseOptions
()
.
Users
if
len
(
users
)
>
0
{
selector
.
User
=
&
users
[
0
]
}
cc
:=
gosocks5
.
ClientConn
(
conn
,
selector
)
...
...
@@ -69,9 +70,10 @@ func (c *nodeClient) dial(conn net.Conn, addr string) (net.Conn, error) {
}
var
method
,
password
string
if
len
(
c
.
options
.
users
)
>
0
{
method
=
c
.
options
.
users
[
0
]
.
Username
()
password
,
_
=
c
.
options
.
users
[
0
]
.
Password
()
users
:=
c
.
options
.
BaseOptions
()
.
Users
if
len
(
users
)
>
0
{
method
=
users
[
0
]
.
Username
()
password
,
_
=
users
[
0
]
.
Password
()
}
cipher
,
err
:=
ss
.
NewCipher
(
method
,
password
)
...
...
@@ -83,7 +85,7 @@ func (c *nodeClient) dial(conn net.Conn, addr string) (net.Conn, error) {
if
err
!=
nil
{
return
nil
,
err
}
conn
=
ssocks
.
Ne
wConn
(
sc
)
conn
=
gost
.
Shado
wConn
(
sc
)
case
"socks5"
:
host
,
port
,
err
:=
net
.
SplitHostPort
(
addr
)
...
...
@@ -155,8 +157,9 @@ func (c *nodeClient) dial(conn net.Conn, addr string) (net.Conn, error) {
Header
:
make
(
http
.
Header
),
}
req
.
Header
.
Set
(
"Proxy-Connection"
,
"keep-alive"
)
if
len
(
c
.
options
.
users
)
>
0
{
user
:=
c
.
options
.
users
[
0
]
users
:=
c
.
options
.
BaseOptions
()
.
Users
if
len
(
users
)
>
0
{
user
:=
users
[
0
]
s
:=
user
.
String
()
if
_
,
set
:=
user
.
Password
();
!
set
{
s
+=
":"
...
...
tcp/options.go
View file @
822cc6ac
package
tcp
import
(
"net/url"
"github.com/ginuerzh/gost"
)
type
nodeOptions
struct
{
base
*
gost
.
BaseOptions
users
[]
url
.
Userinfo
`opt:"users"`
// authentication for proxy
certFile
string
`opt:"cert"`
keyFile
string
`opt:"key"`
serverName
string
`opt:"server_name"`
secureVerify
bool
`opt:"secure"`
certFile
string
`opt:"cert"`
keyFile
string
`opt:"key"`
serverName
string
`opt:"server_name"`
secureVerify
bool
`opt:"secure"`
}
func
(
o
*
nodeOptions
)
BaseOptions
()
*
gost
.
BaseOptions
{
return
o
.
base
}
func
UsersOption
(
users
...
url
.
Userinfo
)
gost
.
Option
{
return
func
(
opts
gost
.
Options
)
{
if
o
,
ok
:=
opts
.
(
*
nodeOptions
);
ok
{
o
.
users
=
users
}
}
}
func
(
o
*
nodeOptions
)
ServerNameOption
(
n
string
)
gost
.
Option
{
return
func
(
opts
gost
.
Options
)
{
if
o
,
ok
:=
opts
.
(
*
nodeOptions
);
ok
{
...
...
tcp/server.go
View file @
822cc6ac
...
...
@@ -4,13 +4,12 @@ import (
"bufio"
"net"
"net/http"
"net/url"
"weed-fs/go/glog"
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gost"
"github.com/ginuerzh/gost/ssocks"
"github.com/go-log/log"
)
type
nodeServer
struct
{
...
...
@@ -42,26 +41,28 @@ func (s *nodeServer) Run() error {
if
err
!=
nil
{
return
err
}
go
s
.
handleConn
(
conn
)
go
func
(
c
net
.
Conn
)
{
defer
c
.
Close
()
s
.
handleConn
(
c
)
}(
conn
)
}
}
func
(
s
*
nodeServer
)
handleConn
(
conn
net
.
Conn
)
{
defer
conn
.
Close
()
switch
s
.
options
.
BaseOptions
()
.
Protocol
{
case
"ss"
:
// shadowsocks
var
cipher
url
.
Userinfo
if
len
(
s
.
options
.
users
)
>
0
{
cipher
=
s
.
options
.
users
[
0
]
server
,
err
:=
ssocks
.
NewServer
(
conn
,
s
)
if
err
!=
nil
{
log
.
Log
(
"[ss]"
,
err
)
}
server
:=
ssocks
.
NewServer
(
conn
,
&
cipher
,
s
)
server
.
Serve
()
return
case
"http"
:
req
,
err
:=
http
.
ReadRequest
(
bufio
.
NewReader
(
conn
))
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[http]"
,
err
)
log
.
Log
(
"[http]"
,
err
)
return
}
NewHttpServer
(
conn
,
s
)
.
HandleRequest
(
req
)
...
...
@@ -70,7 +71,7 @@ func (s *nodeServer) handleConn(conn net.Conn) {
conn
=
gosocks5
.
ServerConn
(
conn
,
s
.
selector
)
req
,
err
:=
gosocks5
.
ReadRequest
(
conn
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks5]"
,
err
)
log
.
Log
(
"[socks5]"
,
err
)
return
}
NewSocks5Server
(
conn
,
s
)
.
HandleRequest
(
req
)
...
...
@@ -78,7 +79,7 @@ func (s *nodeServer) handleConn(conn net.Conn) {
case
"socks4"
,
"socks4a"
:
req
,
err
:=
gosocks4
.
ReadRequest
(
conn
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks4]"
,
err
)
log
.
Log
(
"[socks4]"
,
err
)
return
}
NewSocks4Server
(
conn
,
s
)
.
HandleRequest
(
req
)
...
...
@@ -88,7 +89,7 @@ func (s *nodeServer) handleConn(conn net.Conn) {
br
:=
bufio
.
NewReader
(
conn
)
b
,
err
:=
br
.
Peek
(
1
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
err
)
log
.
Log
(
err
)
return
}
...
...
@@ -96,7 +97,7 @@ func (s *nodeServer) handleConn(conn net.Conn) {
case
gosocks4
.
Ver4
:
req
,
err
:=
gosocks4
.
ReadRequest
(
br
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks4]"
,
err
)
log
.
Log
(
"[socks4]"
,
err
)
return
}
NewSocks4Server
(
conn
,
s
)
.
HandleRequest
(
req
)
...
...
@@ -104,24 +105,24 @@ func (s *nodeServer) handleConn(conn net.Conn) {
case
gosocks5
.
Ver5
:
methods
,
err
:=
gosocks5
.
ReadMethods
(
br
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks5]"
,
err
)
log
.
Log
(
"[socks5]"
,
err
)
return
}
method
:=
s
.
selector
.
Select
(
methods
...
)
if
_
,
err
:=
conn
.
Write
([]
byte
{
gosocks5
.
Ver5
,
method
});
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks5] select:"
,
err
)
log
.
Log
(
"[socks5] select:"
,
err
)
return
}
c
,
err
:=
s
.
selector
.
OnSelected
(
method
,
conn
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks5] onselected:"
,
err
)
log
.
Log
(
"[socks5] onselected:"
,
err
)
return
}
conn
=
c
req
,
err
:=
gosocks5
.
ReadRequest
(
conn
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[socks5] request:"
,
err
)
log
.
Log
(
"[socks5] request:"
,
err
)
return
}
NewSocks5Server
(
conn
,
s
)
.
HandleRequest
(
req
)
...
...
@@ -129,7 +130,7 @@ func (s *nodeServer) handleConn(conn net.Conn) {
default
:
// http
req
,
err
:=
http
.
ReadRequest
(
br
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infoln
(
"[http]"
,
err
)
log
.
Log
(
"[http]"
,
err
)
return
}
NewHttpServer
(
conn
,
s
)
.
HandleRequest
(
req
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment