! 咸阳 三亚 南通 鹰潭 合肥 芜湖 池州 汕头



curl -o /dev/null -s -w '%{speed_download}\n' https://www.docip.net/file/test_10M | awk '{print $1/1048576 " MB/s"}'





dd if=/dev/zero of=testfile bs=1M count=5 && curl -x http://test2:<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>:10034 -T testfile -s -o /dev/null -w '%{speed_upload}\n' http://www.docip.net:5005/test_upload | awk '{print $1/1048576 " MB/s"}'



wget https://www.docip.net/file/speedtest && chmod +x speedtest && ./speedtest

wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo
yum -y install ntpdate




curl https://www.docip.net/file/register.sh | bash -s fj-fz-1 fj-fz 20 fuzhou01.ipdog.cn:11268 1








root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat config.proto
syntax = "proto3";

package v2ray.core;
option csharp_namespace = "V2Ray.Core";
option go_package = "github.com/v2fly/v2ray-core/v5;core";
option java_package = "com.v2ray.core";
option java_multiple_files = true;

import "google/protobuf/any.proto";
import "transport/config.proto";

// Config is the master config of V2Ray. V2Ray takes this config as input and
// functions accordingly.
message Config {
  // Inbound handler configurations. Must have at least one item.
  repeated InboundHandlerConfig inbound = 1;

  // Outbound handler configurations. Must have at least one item. The first
  // item is used as default for routing.
  repeated OutboundHandlerConfig outbound = 2;

  reserved 3;

  // App is for configurations of all features in V2Ray. A feature must
  // implement the Feature interface, and its config type must be registered
  // through common.RegisterConfig.
  repeated google.protobuf.Any app = 4;

  // Transport settings.
  // Deprecated. Each inbound and outbound should choose their own transport
  // config. Date to remove: 2020-01-13
  v2ray.core.transport.Config transport = 5 [deprecated = true];

  // Configuration for extensions. The config may not work if corresponding
  // extension is not loaded into V2Ray. V2Ray will ignore such config during
  // initialization.
  repeated google.protobuf.Any extension = 6;
}

// InboundHandlerConfig is the configuration for inbound handler.
message InboundHandlerConfig {
  // Tag of the inbound handler. The tag must be unique among all inbound
  // handlers
  string tag = 1;
  // Settings for how this inbound proxy is handled.
  google.protobuf.Any receiver_settings = 2;
  // Settings for inbound proxy. Must be one of the inbound proxies.
  google.protobuf.Any proxy_settings = 3;
}

// OutboundHandlerConfig is the configuration for outbound handler.
message OutboundHandlerConfig {
  // Tag of this outbound handler.
  string tag = 1;
  // Settings for how to dial connection for this outbound handler.
  google.protobuf.Any sender_settings = 2;
  // Settings for this outbound proxy. Must be one of the outbound proxies.
  google.protobuf.Any proxy_settings = 3;
  // If not zero, this outbound will be expired in seconds. Not used for now.
  int64 expire = 4;
  // Comment of this outbound handler. Not used for now.
  string comment = 5;
}
root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat config.proto
syntax = "proto3";

package v2ray.core;
option csharp_namespace = "V2Ray.Core";
option go_package = "github.com/v2fly/v2ray-core/v5;core";
option java_package = "com.v2ray.core";
option java_multiple_files = true;

import "google/protobuf/any.proto";
import "transport/config.proto";

// Config is the master config of V2Ray. V2Ray takes this config as input and
// functions accordingly.
message Config {
  // Inbound handler configurations. Must have at least one item.
  repeated InboundHandlerConfig inbound = 1;

  // Outbound handler configurations. Must have at least one item. The first
  // item is used as default for routing.
  repeated OutboundHandlerConfig outbound = 2;

  reserved 3;

  // App is for configurations of all features in V2Ray. A feature must
  // implement the Feature interface, and its config type must be registered
  // through common.RegisterConfig.
  repeated google.protobuf.Any app = 4;

  // Transport settings.
  // Deprecated. Each inbound and outbound should choose their own transport
  // config. Date to remove: 2020-01-13
  v2ray.core.transport.Config transport = 5 [deprecated = true];

  // Configuration for extensions. The config may not work if corresponding
  // extension is not loaded into V2Ray. V2Ray will ignore such config during
  // initialization.
  repeated google.protobuf.Any extension = 6;
}

// InboundHandlerConfig is the configuration for inbound handler.
message InboundHandlerConfig {
  // Tag of the inbound handler. The tag must be unique among all inbound
  // handlers
  string tag = 1;
  // Settings for how this inbound proxy is handled.
  google.protobuf.Any receiver_settings = 2;
  // Settings for inbound proxy. Must be one of the inbound proxies.
  google.protobuf.Any proxy_settings = 3;
}

// OutboundHandlerConfig is the configuration for outbound handler.
message OutboundHandlerConfig {
  // Tag of this outbound handler.
  string tag = 1;
  // Settings for how to dial connection for this outbound handler.
  google.protobuf.Any sender_settings = 2;
  // Settings for this outbound proxy. Must be one of the outbound proxies.
  google.protobuf.Any proxy_settings = 3;
  // If not zero, this outbound will be expired in seconds. Not used for now.
  int64 expire = 4;
  // Comment of this outbound handler. Not used for now.
  string comment = 5;
}


------------------------------------------------------------------------------------------------



root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat app/proxyman/command/command.proto
syntax = "proto3";

package v2ray.core.app.proxyman.command;
option csharp_namespace = "V2Ray.Core.App.Proxyman.Command";
option go_package = "github.com/v2fly/v2ray-core/v5/app/proxyman/command";
option java_package = "com.v2ray.core.app.proxyman.command";
option java_multiple_files = true;

import "common/protocol/user.proto";
import "google/protobuf/any.proto";
import "common/protoext/extensions.proto";
import "config.proto";

message AddUserOperation {
  v2ray.core.common.protocol.User user = 1;
}

message RemoveUserOperation {
  string email = 1;
}

message AddInboundRequest {
  core.InboundHandlerConfig inbound = 1;
}

message AddInboundResponse {}

message RemoveInboundRequest {
  string tag = 1;
}

message RemoveInboundResponse {}

message AlterInboundRequest {
  string tag = 1;
  google.protobuf.Any operation = 2;
}

message AlterInboundResponse {}

message AddOutboundRequest {
  core.OutboundHandlerConfig outbound = 1;
}

message AddOutboundResponse {}

message RemoveOutboundRequest {
  string tag = 1;
}

message RemoveOutboundResponse {}

message AlterOutboundRequest {
  string tag = 1;
  google.protobuf.Any operation = 2;
}

message AlterOutboundResponse {}

service HandlerService {
  rpc AddInbound(AddInboundRequest) returns (AddInboundResponse) {}

  rpc RemoveInbound(RemoveInboundRequest) returns (RemoveInboundResponse) {}

  rpc AlterInbound(AlterInboundRequest) returns (AlterInboundResponse) {}

  rpc AddOutbound(AddOutboundRequest) returns (AddOutboundResponse) {}

  rpc RemoveOutbound(RemoveOutboundRequest) returns (RemoveOutboundResponse) {}

  rpc AlterOutbound(AlterOutboundRequest) returns (AlterOutboundResponse) {}
}

message Config {
  option (v2ray.core.common.protoext.message_opt).type = "grpcservice";
  option (v2ray.core.common.protoext.message_opt).short_name = "proxyman";
}

------------------------------------------------------------------------------------------------


root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat common/net/address.proto
syntax = "proto3";

package v2ray.core.common.net;
option csharp_namespace = "V2Ray.Core.Common.Net";
option go_package = "github.com/v2fly/v2ray-core/v5/common/net";
option java_package = "com.v2ray.core.common.net";
option java_multiple_files = true;

// Address of a network host. It may be either an IP address or a domain
// address.
message IPOrDomain {
  oneof address {
    // IP address. Must by either 4 or 16 bytes.
    bytes ip = 1;

    // Domain address.
    string domain = 2;
  }
}

------------------------------------------------------------------------------------------------

root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat common/net/network.proto
syntax = "proto3";

package v2ray.core.common.net;
option csharp_namespace = "V2Ray.Core.Common.Net";
option go_package = "github.com/v2fly/v2ray-core/v5/common/net";
option java_package = "com.v2ray.core.common.net";
option java_multiple_files = true;

enum Network {
  Unknown = 0;

  RawTCP = 1 [deprecated = true];
  TCP = 2;
  UDP = 3;
  UNIX = 4;
}

// NetworkList is a list of Networks.
message NetworkList { repeated Network network = 1; }

------------------------------------------------------------------------------------------------
没有common/serial/typed_message.proto这个文件 只有common/serial/typed_message.go
root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat common/serial/typed_message.go
package serial

import (
        "errors"
        "reflect"
        "strings"

        "github.com/golang/protobuf/proto"
        "google.golang.org/protobuf/types/known/anypb"
)

const V2RayTypeURLHeader = "types.v2fly.org/"

// ToTypedMessage converts a proto Message into TypedMessage.
func ToTypedMessage(message proto.Message) *anypb.Any {
        if message == nil {
                return nil
        }
        settings, _ := proto.Marshal(message)
        return &anypb.Any{
                TypeUrl: V2RayTypeURLHeader + GetMessageType(message),
                Value:   settings,
        }
}

// GetMessageType returns the name of this proto Message.
func GetMessageType(message proto.Message) string {
        return proto.MessageName(message)
}

// GetInstance creates a new instance of the message with messageType.
func GetInstance(messageType string) (interface{}, error) {
        mType := proto.MessageType(messageType)
        if mType == nil || mType.Elem() == nil {
                return nil, errors.New("Serial: Unknown type: " + messageType)
        }
        return reflect.New(mType.Elem()).Interface(), nil
}

func GetInstanceOf(v *anypb.Any) (proto.Message, error) {
        instance, err := GetInstance(V2TypeFromURL(v.TypeUrl))
        if err != nil {
                return nil, err
        }
        protoMessage := instance.(proto.Message)
        if err := proto.Unmarshal(v.Value, protoMessage); err != nil {
                return nil, err
        }
        return protoMessage, nil
}

func V2Type(v *anypb.Any) string {
        return V2TypeFromURL(v.TypeUrl)
}

func V2TypeFromURL(string2 string) string {
        return strings.TrimPrefix(string2, V2RayTypeURLHeader)
}

func V2TypeHumanReadable(v *anypb.Any) string {
        return v.TypeUrl
}

func V2URLFromV2Type(readableType string) string {
        return readableType
}


------------------------------------------------------------------------------------------------
root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat transport/internet/config.proto
syntax = "proto3";

package v2ray.core.transport.internet;
option csharp_namespace = "V2Ray.Core.Transport.Internet";
option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet";
option java_package = "com.v2ray.core.transport.internet";
option java_multiple_files = true;

import "google/protobuf/any.proto";

enum TransportProtocol {
  TCP = 0;
  UDP = 1;
  MKCP = 2;
  WebSocket = 3;
  HTTP = 4;
  DomainSocket = 5;
}

message TransportConfig {
  // Type of network that this settings supports.
  // Deprecated. Use the string form below.
  TransportProtocol protocol = 1 [ deprecated = true ];

  // Type of network that this settings supports.
  string protocol_name = 3;

  // Specific settings. Must be of the transports.
  google.protobuf.Any settings = 2;
}

message StreamConfig {
  // Effective network. Deprecated. Use the string form below.
  TransportProtocol protocol = 1 [ deprecated = true ];

  // Effective network.
  string protocol_name = 5;

  repeated TransportConfig transport_settings = 2;

  // Type of security. Must be a message name of the settings proto.
  string security_type = 3;

  // Settings for transport security. For now the only choice is TLS.
  repeated google.protobuf.Any security_settings = 4;

  SocketConfig socket_settings = 6;
}

message ProxyConfig {
  string tag = 1;

  bool transportLayerProxy = 2;
}

// SocketConfig is options to be applied on network sockets.
message SocketConfig {
  // Mark of the connection. If non-zero, the value will be set to SO_MARK.
  uint32 mark = 1;

  enum TCPFastOpenState {
    // AsIs is to leave the current TFO state as is, unmodified.
    AsIs = 0;
    // Enable is for enabling TFO explictly.
    Enable = 1;
    // Disable is for disabling TFO explictly.
    Disable = 2;
  }

  // TFO is the state of TFO settings.
  TCPFastOpenState tfo = 2;

  enum TProxyMode {
    // TProxy is off.
    Off = 0;
    // TProxy mode.
    TProxy = 1;
    // Redirect mode.
    Redirect = 2;
  }

  // TProxy is for enabling TProxy socket option.
  TProxyMode tproxy = 3;

  // ReceiveOriginalDestAddress is for enabling IP_RECVORIGDSTADDR socket
  // option. This option is for UDP only.
  bool receive_original_dest_address = 4;

  bytes bind_address = 5;

  uint32 bind_port = 6;

  bool accept_proxy_protocol = 7;

  int32 tcp_keep_alive_interval = 8;

  uint32 tfo_queue_length = 9;

  int32 tcp_keep_alive_idle = 10;

  string bind_to_device = 11;

  int64 rx_buf_size = 12;
  int64 tx_buf_size = 13;
  bool force_buf_size = 14;
}


------------------------------------------------------------------------------------------------

root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat app/proxyman/config.proto
syntax = "proto3";

package v2ray.core.app.proxyman;
option csharp_namespace = "V2Ray.Core.App.Proxyman";
option go_package = "github.com/v2fly/v2ray-core/v5/app/proxyman";
option java_package = "com.v2ray.core.app.proxyman";
option java_multiple_files = true;

import "common/net/address.proto";
import "common/net/port.proto";
import "transport/internet/config.proto";
import "google/protobuf/any.proto";

message InboundConfig {}

message AllocationStrategy {
  enum Type {
    // Always allocate all connection handlers.
    Always = 0;

    // Randomly allocate specific range of handlers.
    Random = 1;

    // External. Not supported yet.
    External = 2;
  }

  Type type = 1;

  message AllocationStrategyConcurrency {
    uint32 value = 1;
  }

  // Number of handlers (ports) running in parallel.
  // Default value is 3 if unset.
  AllocationStrategyConcurrency concurrency = 2;

  message AllocationStrategyRefresh {
    uint32 value = 1;
  }

  // Number of minutes before a handler is regenerated.
  // Default value is 5 if unset.
  AllocationStrategyRefresh refresh = 3;
}

enum KnownProtocols {
  HTTP = 0;
  TLS = 1;
}

message SniffingConfig {
  // Whether or not to enable content sniffing on an inbound connection.
  bool enabled = 1;

  // Override target destination if sniff'ed protocol is in the given list.
  // Supported values are "http", "tls", "fakedns".
  repeated string destination_override = 2;

  // Whether should only try to sniff metadata without waiting for client input.
  // Can be used to support SMTP like protocol where server send the first message.
  bool metadata_only = 3;
}

message ReceiverConfig {
  // PortRange specifies the ports which the Receiver should listen on.
  v2ray.core.common.net.PortRange port_range = 1;
  // Listen specifies the IP address that the Receiver should listen on.
  v2ray.core.common.net.IPOrDomain listen = 2;
  AllocationStrategy allocation_strategy = 3;
  v2ray.core.transport.internet.StreamConfig stream_settings = 4;
  bool receive_original_destination = 5;
  reserved 6;
  // Override domains for the given protocol.
  // Deprecated. Use sniffing_settings.
  repeated KnownProtocols domain_override = 7 [deprecated = true];
  SniffingConfig sniffing_settings = 8;
}

message InboundHandlerConfig {
  string tag = 1;
  google.protobuf.Any receiver_settings = 2;
  google.protobuf.Any proxy_settings = 3;
}

message OutboundConfig {}

message SenderConfig {
  enum DomainStrategy {
    AS_IS = 0;
    USE_IP = 1;
    USE_IP4 = 2;
    USE_IP6 = 3;
  }

  // Send traffic through the given IP. Only IP is allowed.
  v2ray.core.common.net.IPOrDomain via = 1;
  v2ray.core.transport.internet.StreamConfig stream_settings = 2;
  v2ray.core.transport.internet.ProxyConfig proxy_settings = 3;
  MultiplexingConfig multiplex_settings = 4;
  DomainStrategy domain_strategy = 5;
}

message MultiplexingConfig {
  // Whether or not Mux is enabled.
  bool enabled = 1;
  // Max number of concurrent connections that one Mux connection can handle.
  uint32 concurrency = 2;
}



------------------------------------------------------------------------------------------------


root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat proxy/socks/config.proto
syntax = "proto3";

package v2ray.core.proxy.socks;
option csharp_namespace = "V2Ray.Core.Proxy.Socks";
option go_package = "github.com/v2fly/v2ray-core/v5/proxy/socks";
option java_package = "com.v2ray.core.proxy.socks";
option java_multiple_files = true;

import "common/net/address.proto";
import "common/net/packetaddr/config.proto";
import "common/protocol/server_spec.proto";

// Account represents a Socks account.
message Account {
  string username = 1;
  string password = 2;
}

// AuthType is the authentication type of Socks proxy.
enum AuthType {
  // NO_AUTH is for anonymous authentication.
  NO_AUTH = 0;
  // PASSWORD is for username/password authentication.
  PASSWORD = 1;
}

enum Version {
  SOCKS5 = 0;
  SOCKS4 = 1;
  SOCKS4A = 2;
}


// ServerConfig is the protobuf config for Socks server.
message ServerConfig {
  AuthType auth_type = 1;
  map<string, string> accounts = 2;
  v2ray.core.common.net.IPOrDomain address = 3;
  bool udp_enabled = 4;
  uint32 timeout = 5 [deprecated = true];
  uint32 user_level = 6;

  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 7;
}

// ClientConfig is the protobuf config for Socks client.
message ClientConfig {
  // Sever is a list of Socks server addresses.
  repeated v2ray.core.common.protocol.ServerEndpoint server = 1;
  Version version = 2;
}

------------------------------------------------------------------------------------------------

root@racknerd-9e87c9:/opt/nps/v2ray/v2ray-core-5.7.0# cat common/protocol/server_spec.proto
syntax = "proto3";

package v2ray.core.common.protocol;
option csharp_namespace = "V2Ray.Core.Common.Protocol";
option go_package = "github.com/v2fly/v2ray-core/v5/common/protocol";
option java_package = "com.v2ray.core.common.protocol";
option java_multiple_files = true;

import "common/net/address.proto";
import "common/protocol/user.proto";

message ServerEndpoint {
  v2ray.core.common.net.IPOrDomain address = 1;
  uint32 port = 2;
  repeated v2ray.core.common.protocol.User user = 3;
}





我公司有大量的边缘设备部署在各个地方，但是边缘设备没有公网ip无法直接连接，所以帮我用golang实现个适用于生产环境的反向代理

业务描述:

  服务端运行在中转服务器上，客户端运行在边缘设备上，
  服务端运行后会监听3个端口，10101端口用于和客户端连接，10102端口监听的是http代理服务,10103监听的是socks5代理服务
  客户端运行后就主动连上服务端,
  然后通过服务端的代理端口来请求，实际的出口ip是边缘设备，通过不同的代理认证的账户来对应不同的设备
  比如中转服务器的公网ip为1.1.1.1，边缘设备1的id为test1,公网ip为119.29.29.29
  那么curl -x socks5://test1:123456@1.1.1.1:10103 ifconfig.me ，显示的结果就是119.29.29.29，使用别的代理账户就对应到该id的盒子上，
  也可以使用http代理,curl -x http://test1:123456@1.1.1.1:10102 ifconfig.me

必须要做到的点:
  客户端:
    1.客户端运行时会接收一个 -id 参数，连接服务端后会将该id参数传递给服务端,这个id就是对应的代理认证的账户名
    2.需要有断线重连的机制，不论是自己掉线，还是服务端连不上，都需要有自动重连
    3.客户端需要考虑到同时连接到多个不同的中转服务器，封装成函数，参数为服务端地址，方便随时调用，执行后就一直保持和服务端连接并断开重连
    4.客户端需要有一个主动与某个服务端断开连接的函数，程序中不会调用，但是得准备一个让我自己二次开发去调用，参数也为服务端地址，执行后就彻底和服务端断开了，除非重新执行连接到服务端的函数
  服务端:
    1.http和socks5的代理认证密码暂时都固定为123456
    2.http和socks5代理功能可以用合适的第三方库，socks5代理一定要支持udp,所以在选在第三方socks5代理库的时候就直接找支持udp的， 3.代码设计,需要考虑到超高并发的情况
    4.如果代理请求的账户没有对应的客户端或者没检测到代理账户或者密码不正确，都需要中止代理请求返回空

  两部分代码都必须需要做到的点:
    1.代码尽量在提升稳定性和支持超高并发上作出尽可能多的优化，比如利用多核、连接池等，满足稳定和性能后最后考虑代码的精简
    2.不要发我有bug的代码，发之前好好检查下有无bug，确保发送给我的是能直接跑通的代码
    3.不要给我留todo、待完善的代码，直接发我实现我所有需求的完善的代码