mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 10:08:15 -05:00
Docs
This commit is contained in:
parent
a0fda39274
commit
49441a5050
@ -4,7 +4,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -96,15 +95,5 @@ func (this *Connection) SysFd() (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getSysFd(conn net.Conn) (int, error) {
|
func getSysFd(conn net.Conn) (int, error) {
|
||||||
cv := reflect.ValueOf(conn)
|
|
||||||
switch ce := cv.Elem(); ce.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
netfd := ce.FieldByName("conn").FieldByName("fd")
|
|
||||||
switch fe := netfd.Elem(); fe.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
fd := fe.FieldByName("sysfd")
|
|
||||||
return int(fd.Int()), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, ErrInvalidConn
|
return 0, ErrInvalidConn
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package ws
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@ -44,7 +45,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
|
func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
|
||||||
//internet.DialToDest(src, dest)
|
|
||||||
commonDial := func(network, addr string) (net.Conn, error) {
|
commonDial := func(network, addr string) (net.Conn, error) {
|
||||||
return internet.DialToDest(src, dest)
|
return internet.DialToDest(src, dest)
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
|
|||||||
if the port you are using is not well-known,
|
if the port you are using is not well-known,
|
||||||
specify it to avoid this process.
|
specify it to avoid this process.
|
||||||
|
|
||||||
We will re return "CRASH"turn "unknown" if we can't guess it, cause Dial to fail.
|
We will return "CRASH"turn "unknown" if we can't guess it, cause Dial to fail.
|
||||||
*/
|
*/
|
||||||
case 80:
|
case 80:
|
||||||
case 8080:
|
case 8080:
|
||||||
@ -110,8 +110,11 @@ func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
|
|||||||
uri := func(dst v2net.Destination, pto string, path string) string {
|
uri := func(dst v2net.Destination, pto string, path string) string {
|
||||||
return fmt.Sprintf("%v://%v:%v/%v", pto, dst.NetAddr(), dst.Port(), path)
|
return fmt.Sprintf("%v://%v:%v/%v", pto, dst.NetAddr(), dst.Port(), path)
|
||||||
}(dest, effpto, effectiveConfig.Path)
|
}(dest, effpto, effectiveConfig.Path)
|
||||||
conn, _, err := dialer.Dial(uri, nil)
|
|
||||||
|
conn, resp, err := dialer.Dial(uri, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
reason, reasonerr := ioutil.ReadAll(resp.Body)
|
||||||
|
log.Info(string(reason), reasonerr)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return func() internet.Connection {
|
return func() internet.Connection {
|
||||||
|
@ -62,7 +62,6 @@ func (wsl *WSListener) listenws(address v2net.Address, port v2net.Port) error {
|
|||||||
con.Close()
|
con.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//con.retloc.Wait()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
})
|
})
|
||||||
|
34
transport/internet/ws/ws.go
Normal file
34
transport/internet/ws/ws.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*Package ws implements Websocket transport
|
||||||
|
|
||||||
|
Websocket transport implements a HTTP(S) compliable, surveillance proof transport method with plausible deniability.
|
||||||
|
|
||||||
|
To configure such a listener, set streamSettings to be ws. A http(s) listener will be listening at the port you have configured.
|
||||||
|
|
||||||
|
There is additional configure can be made at transport configure.
|
||||||
|
|
||||||
|
"wsSettings":{
|
||||||
|
"Path":"ws", // the path our ws handler bind
|
||||||
|
"Pto": "wss/ws", // the transport protocol we are using ws or wss(listen ws with tls)
|
||||||
|
"Cert":"cert.pem", // if you have configured to use wss, configure your cert here
|
||||||
|
"PrivKey":"priv.pem" //if you have configured to use wss, configure your privatekey here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
To configure such a Dialer, set streamSettings to be ws.
|
||||||
|
|
||||||
|
There is additional configure can be made at transport configure.
|
||||||
|
|
||||||
|
"wsSettings":{
|
||||||
|
"Path":"ws", // the path our ws handler bind
|
||||||
|
"Pto": "wss/ws", // the transport protocol we are using ws or wss(listen ws with tls)
|
||||||
|
}
|
||||||
|
|
||||||
|
It is worth noting that accepting a non-valid cert is not supported as a self-signed or invalid cert can be a sign of a website that is not correctly configured and lead to additional investigation.
|
||||||
|
|
||||||
|
|
||||||
|
This transport was disscussed at
|
||||||
|
https://github.com/v2ray/v2ray-core/issues/224
|
||||||
|
https://trello.com/c/3uCCeBkC/8-add-websocket-transport
|
||||||
|
|
||||||
|
*/
|
||||||
|
package ws
|
@ -18,7 +18,6 @@ type wsconn struct {
|
|||||||
readBuffer *bufio.Reader
|
readBuffer *bufio.Reader
|
||||||
connClosing bool
|
connClosing bool
|
||||||
reusable bool
|
reusable bool
|
||||||
retloc *sync.Cond
|
|
||||||
rlock *sync.Mutex
|
rlock *sync.Mutex
|
||||||
wlock *sync.Mutex
|
wlock *sync.Mutex
|
||||||
}
|
}
|
||||||
@ -59,7 +58,6 @@ func (ws *wsconn) Read(b []byte) (n int, err error) {
|
|||||||
if ws.readBuffer == nil {
|
if ws.readBuffer == nil {
|
||||||
err = getNewBuffer()
|
err = getNewBuffer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//ws.Close()
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +75,6 @@ func (ws *wsconn) Read(b []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
//ws.Close()
|
|
||||||
return n, err
|
return n, err
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -89,14 +86,18 @@ func (ws *wsconn) Read(b []byte) (n int, err error) {
|
|||||||
|
|
||||||
func (ws *wsconn) Write(b []byte) (n int, err error) {
|
func (ws *wsconn) Write(b []byte) (n int, err error) {
|
||||||
ws.wlock.Lock()
|
ws.wlock.Lock()
|
||||||
|
/*
|
||||||
|
process can crash as websocket report "concurrent write to websocket connection"
|
||||||
|
even if lock is persent.
|
||||||
|
|
||||||
|
It is yet to know how to prevent this but a workaround is the only choice.
|
||||||
|
*/
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println("WS workaround: recover", r)
|
fmt.Println("WS workaround: recover", r)
|
||||||
ws.wlock.Unlock()
|
ws.wlock.Unlock()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
//defer
|
|
||||||
//ws.checkifRWAfterClosing()
|
|
||||||
if ws.connClosing {
|
if ws.connClosing {
|
||||||
|
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
@ -111,12 +112,10 @@ func (ws *wsconn) Write(b []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
n, err = wr.Write(b)
|
n, err = wr.Write(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//ws.Close()
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
err = wr.Close()
|
err = wr.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//ws.Close()
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
@ -129,7 +128,6 @@ func (ws *wsconn) Close() error {
|
|||||||
ws.connClosing = true
|
ws.connClosing = true
|
||||||
ws.wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add((time.Second * 5)))
|
ws.wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add((time.Second * 5)))
|
||||||
err := ws.wsc.Close()
|
err := ws.wsc.Close()
|
||||||
ws.retloc.Broadcast()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func (ws *wsconn) LocalAddr() net.Addr {
|
func (ws *wsconn) LocalAddr() net.Addr {
|
||||||
@ -159,25 +157,12 @@ func (ws *wsconn) SetWriteDeadline(t time.Time) error {
|
|||||||
return ws.wsc.SetWriteDeadline(t)
|
return ws.wsc.SetWriteDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *wsconn) checkifRWAfterClosing() {
|
|
||||||
if ws.connClosing {
|
|
||||||
log.Error("WS transport: Read or Write After Conn have been marked closing, this can be dangerous.")
|
|
||||||
//panic("WS transport: Read or Write After Conn have been marked closing. Please report this crash to developer.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ws *wsconn) setup() {
|
func (ws *wsconn) setup() {
|
||||||
ws.connClosing = false
|
ws.connClosing = false
|
||||||
|
|
||||||
ws.rlock = &sync.Mutex{}
|
ws.rlock = &sync.Mutex{}
|
||||||
ws.wlock = &sync.Mutex{}
|
ws.wlock = &sync.Mutex{}
|
||||||
|
|
||||||
initConnectedCond := func() {
|
|
||||||
rsl := &sync.Mutex{}
|
|
||||||
ws.retloc = sync.NewCond(rsl)
|
|
||||||
}
|
|
||||||
|
|
||||||
initConnectedCond()
|
|
||||||
ws.pingPong()
|
ws.pingPong()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +191,6 @@ func (ws *wsconn) pingPong() {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-pongRcv:
|
case <-pongRcv:
|
||||||
//log.Debug("WS:Pong~" + ws.wsc.UnderlyingConn().RemoteAddr().String())
|
|
||||||
break
|
break
|
||||||
case <-tick.C:
|
case <-tick.C:
|
||||||
log.Debug("WS:Closing as ping is not responded~" + ws.wsc.UnderlyingConn().LocalAddr().String() + "-" + ws.wsc.UnderlyingConn().RemoteAddr().String())
|
log.Debug("WS:Closing as ping is not responded~" + ws.wsc.UnderlyingConn().LocalAddr().String() + "-" + ws.wsc.UnderlyingConn().RemoteAddr().String())
|
||||||
|
Loading…
Reference in New Issue
Block a user