shadowsocks / shadowsocks-go

go port of shadowsocks (Deprecated)
http://shadowsocks.github.io/shadowsocks-go
Apache License 2.0
6.61k stars 3.32k forks source link

Suggestions for reconstruction on this repo #192

Open arthurkiller opened 7 years ago

arthurkiller commented 7 years ago

I have read this repo and here is some advises:

Last day of work before new year , forgive me give about so many suggestions. I must be lacking of work LOL.

Happy new year dude

arthurkiller commented 7 years ago

191 this can be closed

lixin9311 commented 7 years ago

Thank you for the suggestions.

  1. I will finish the lint and documents in next major update. (WIP)
  2. reflection is only used to parse the config file so it doesn't hurt the performance, just as the original author said

    Using reflection here is not necessary, but it's a good exercise.

  3. WIP
  4. A log interface is good.
  5. Config file is using JSON format, to keep consistency with other shadowsocks implementations.
  6. I think leaky buffer and buffer pool is the same thing.
  7. The merge code might not be used. safe to delete.

Thank you for suggestions.

lixin9311 commented 7 years ago

About next major update, I've almost finished reconstruction of core code.

Since you are interested in this project, you can check it out here https://github.com/lixin9311/shadowsocks-go/tree/next

Currently, only the server program works. But it's really easy to use the package. Just import and a few lines of code..

func run(port, password string, auth bool) {
    ln, err := ss.Listen("tcp", ":"+port, config)
    if err != nil {
        return
    }
    defer ln.Close()
    for {
        conn, host, err := ln.Accept()
        if err != nil {
            return
        }
        remote, _ := net.Dial("tcp", host)
        go ss.PipeThenClose(conn, remote)
        go ss.PipeThenClose(remote, conn)
    }
}

func runUDP(port, password string, auth bool) {
    SecurePacketConn, err := ss.ListenPacket("udp", ":"+port, config)
    if err != nil {
        return
    }
    defer SecurePacketConn.Close()
    buf := make([]byte, 4096)
    for {
        n, src, err := SecurePacketConn.ReadFrom(buf)
        if err != nil {
            return
        }
        host, headerLen, compatibleMode, err := ss.UDPGetRequest(buf[:n], auth)
        if err != nil {
            continue
        }
        if compatibleMode {
            ss.ForwardUDPConn(SecurePacketConn.ForceOTA(), src, host, buf[:n], headerLen)
        } else {
            ss.ForwardUDPConn(SecurePacketConn, src, host, buf[:n], headerLen)
        }
    }
}

A basic server will be set up.

There are some inconsistencies in the code for now, like the config, because it's still WIP.

Next step, I'm going to finish the reconstruction and improve client and server program.

arthurkiller commented 7 years ago

Awesome work. Thx a lot dude

arthurkiller commented 7 years ago

@lixin9311 After really a long time I finished the reconstruct based on your next branch.

todo

arthurkiller commented 7 years ago

@lixin9311 how do you think about this

arthurkiller commented 7 years ago

I have come out a suit of encryption interface for Encrypter packet.

We will get 4 interface

type AEADCipher interface {
    KeySize() int
    SaltSize() int
    Encrypter(salt []byte) (cipher.AEAD, error)
    Decrypter(salt []byte) (cipher.AEAD, error)
}
type StreamCipher interface {
    KeySize() int
    IVSize() int
    Encrypter(iv []byte) cipher.Stream
    Decrypter(iv []byte) cipher.Stream
}

type ConnectionCoder interface {
    Read([]byte) (int, error)
    Write([]byte) (int, error)
}
type PacketCoder interface {
    ReadFrom([]byte) (int, net.Addr, error)
    WriteTo([]byte, net.Addr) (int, error)
}

Combine them and you can get 4 Cipher

type AEADConnectionCipher interface {
    AEADCipher
    ConnectionCoder
}
type AEADPacketCipher interface {
    AEADCipher
    PacketCoder
}
type StreamConnectionCipher interface {
    StreamCipher
    ConnectionCoder
}
type StreamPacketCipher interface {
    StreamCipher
    PacketCoder
}

This can be easy to extend and with low coupling. On the other hand, this can be a little complicated.

I want this repo not only a cmd tool but also easy to extend and can be used as a package for golang server developer.

@Galaxy0419 @Aniark @lixin9311

arthurkiller commented 7 years ago

And here also give out a TODO list, some feature on this is WIP and some is TBD/TODO

I wander the priority of this list. (Now it is my priority)