Procházet zdrojové kódy

feat(vpn): specify vpn proto during initialization

- CLI
- Core API(vpn)
- RPC

Closes #30
Mustafa Arici před 8 roky
rodič
revize
aeeeb98322
11 změnil soubory, kde provedl 190 přidání a 66 odebrání
  1. 11 1
      api/rpc.go
  2. 4 4
      bindata/bindata.go
  3. 17 1
      cmd/ovpm/vpn.go
  4. 19 10
      net_test.go
  5. 70 25
      pb/vpn.pb.go
  6. 8 0
      pb/vpn.proto
  7. 15 0
      pb/vpn.swagger.json
  8. 1 1
      template/server.conf.tmpl
  9. 10 11
      user_test.go
  10. 23 1
      vpn.go
  11. 12 12
      vpn_test.go

+ 11 - 1
api/rpc.go

@@ -163,6 +163,7 @@ func (s *VPNService) Status(ctx context.Context, req *pb.VPNStatusRequest) (*pb.
 		SerialNumber: server.SerialNumber,
 		Hostname:     server.Hostname,
 		Port:         server.Port,
+		Proto:        server.Proto,
 		Cert:         server.Cert,
 		CACert:       server.CACert,
 		Net:          server.Net,
@@ -174,7 +175,16 @@ func (s *VPNService) Status(ctx context.Context, req *pb.VPNStatusRequest) (*pb.
 
 func (s *VPNService) Init(ctx context.Context, req *pb.VPNInitRequest) (*pb.VPNInitResponse, error) {
 	logrus.Debugf("rpc call: vpn init")
-	if err := ovpm.Init(req.Hostname, req.Port); err != nil {
+	var proto string
+	switch req.Protopref {
+	case pb.VPNProto_TCP:
+		proto = ovpm.TCPProto
+	case pb.VPNProto_UDP:
+		proto = ovpm.UDPProto
+	case pb.VPNProto_NOPREF:
+		proto = ovpm.UDPProto
+	}
+	if err := ovpm.Init(req.Hostname, req.Port, proto); err != nil {
 		logrus.Errorf("server can not be created: %v", err)
 	}
 	return &pb.VPNInitResponse{}, nil

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 4 - 4
bindata/bindata.go


+ 17 - 1
cmd/ovpm/vpn.go

@@ -32,6 +32,7 @@ var vpnStatusCommand = cli.Command{
 		table.Append([]string{"Name", res.Name})
 		table.Append([]string{"Hostname", res.Hostname})
 		table.Append([]string{"Port", res.Port})
+		table.Append([]string{"Proto", res.Proto})
 		table.Append([]string{"Network", res.Net})
 		table.Append([]string{"Netmask", res.Mask})
 		table.Append([]string{"Created At", res.CreatedAt})
@@ -55,6 +56,10 @@ var vpnInitCommand = cli.Command{
 			Usage: "port number of the vpn server",
 			Value: ovpm.DefaultVPNPort,
 		},
+		cli.BoolFlag{
+			Name:  "tcp, t",
+			Usage: "use TCP for vpn protocol, instead of UDP",
+		},
 	},
 	Action: func(c *cli.Context) error {
 		action = "vpn:init"
@@ -71,6 +76,17 @@ var vpnInitCommand = cli.Command{
 			port = ovpm.DefaultVPNPort
 		}
 
+		tcp := c.Bool("tcp")
+
+		var proto pb.VPNProto
+
+		switch tcp {
+		case true:
+			proto = pb.VPNProto_TCP
+		default:
+			proto = pb.VPNProto_UDP
+		}
+
 		conn := getConn(c.GlobalString("daemon-port"))
 		defer conn.Close()
 		vpnSvc := pb.NewVPNServiceClient(conn)
@@ -90,7 +106,7 @@ var vpnInitCommand = cli.Command{
 			okayResponses := []string{"y", "Y", "yes", "Yes", "YES"}
 			nokayResponses := []string{"n", "N", "no", "No", "NO"}
 			if stringInSlice(response, okayResponses) {
-				if _, err := vpnSvc.Init(context.Background(), &pb.VPNInitRequest{Hostname: hostname, Port: port}); err != nil {
+				if _, err := vpnSvc.Init(context.Background(), &pb.VPNInitRequest{Hostname: hostname, Port: port, Protopref: proto}); err != nil {
 					logrus.Errorf("server can not be initialized: %v", err)
 					os.Exit(1)
 					return err

+ 19 - 10
net_test.go

@@ -9,7 +9,7 @@ func TestVPNCreateNewNetwork(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	// Test:
@@ -56,7 +56,7 @@ func TestVPNDeleteNetwork(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	// Test:
@@ -94,7 +94,7 @@ func TestVPNGetNetwork(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	// Test:
@@ -129,7 +129,7 @@ func TestVPNGetAllNetworks(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	// Test:
@@ -175,7 +175,7 @@ func TestNetAssociate(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	// Test:
@@ -213,7 +213,10 @@ func TestNetDissociate(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	err := Init("localhost", "", UDPProto)
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	// Prepare:
 	// Test:
@@ -221,9 +224,15 @@ func TestNetDissociate(t *testing.T) {
 	cidrStr := "192.168.1.0/24"
 	netType := SERVERNET
 	userName := "testUser2"
-	user, _ := CreateNewUser(userName, "123", false, 0)
+	user, err := CreateNewUser(userName, "123", false, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
 
-	n, _ := CreateNewNetwork(netName, cidrStr, netType, "")
+	n, err := CreateNewNetwork(netName, cidrStr, netType, "")
+	if err != nil {
+		t.Fatal(err)
+	}
 	n.Associate(user.Username)
 
 	n = nil
@@ -234,7 +243,7 @@ func TestNetDissociate(t *testing.T) {
 		t.Fatalf("network.Users count is expexted to be %d, but it's %d", 1, count)
 	}
 
-	err := n.Dissociate(user.Username)
+	err = n.Dissociate(user.Username)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
@@ -257,7 +266,7 @@ func TestNetGetAssociatedUsers(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	// Test:

+ 70 - 25
pb/vpn.pb.go

@@ -18,6 +18,30 @@ var _ = proto.Marshal
 var _ = fmt.Errorf
 var _ = math.Inf
 
+type VPNProto int32
+
+const (
+	VPNProto_NOPREF VPNProto = 0
+	VPNProto_UDP    VPNProto = 1
+	VPNProto_TCP    VPNProto = 2
+)
+
+var VPNProto_name = map[int32]string{
+	0: "NOPREF",
+	1: "UDP",
+	2: "TCP",
+}
+var VPNProto_value = map[string]int32{
+	"NOPREF": 0,
+	"UDP":    1,
+	"TCP":    2,
+}
+
+func (x VPNProto) String() string {
+	return proto.EnumName(VPNProto_name, int32(x))
+}
+func (VPNProto) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
+
 type VPNStatusRequest struct {
 }
 
@@ -27,8 +51,9 @@ func (*VPNStatusRequest) ProtoMessage()               {}
 func (*VPNStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
 
 type VPNInitRequest struct {
-	Hostname string `protobuf:"bytes,1,opt,name=Hostname" json:"Hostname,omitempty"`
-	Port     string `protobuf:"bytes,2,opt,name=Port" json:"Port,omitempty"`
+	Hostname  string   `protobuf:"bytes,1,opt,name=Hostname" json:"Hostname,omitempty"`
+	Port      string   `protobuf:"bytes,2,opt,name=Port" json:"Port,omitempty"`
+	Protopref VPNProto `protobuf:"varint,3,opt,name=Protopref,enum=pb.VPNProto" json:"Protopref,omitempty"`
 }
 
 func (m *VPNInitRequest) Reset()                    { *m = VPNInitRequest{} }
@@ -50,6 +75,13 @@ func (m *VPNInitRequest) GetPort() string {
 	return ""
 }
 
+func (m *VPNInitRequest) GetProtopref() VPNProto {
+	if m != nil {
+		return m.Protopref
+	}
+	return VPNProto_NOPREF
+}
+
 type VPNStatusResponse struct {
 	Name         string `protobuf:"bytes,1,opt,name=Name" json:"Name,omitempty"`
 	SerialNumber string `protobuf:"bytes,2,opt,name=SerialNumber" json:"SerialNumber,omitempty"`
@@ -60,6 +92,7 @@ type VPNStatusResponse struct {
 	Net          string `protobuf:"bytes,7,opt,name=Net" json:"Net,omitempty"`
 	Mask         string `protobuf:"bytes,8,opt,name=Mask" json:"Mask,omitempty"`
 	CreatedAt    string `protobuf:"bytes,9,opt,name=CreatedAt" json:"CreatedAt,omitempty"`
+	Proto        string `protobuf:"bytes,10,opt,name=Proto" json:"Proto,omitempty"`
 }
 
 func (m *VPNStatusResponse) Reset()                    { *m = VPNStatusResponse{} }
@@ -130,6 +163,13 @@ func (m *VPNStatusResponse) GetCreatedAt() string {
 	return ""
 }
 
+func (m *VPNStatusResponse) GetProto() string {
+	if m != nil {
+		return m.Proto
+	}
+	return ""
+}
+
 type VPNInitResponse struct {
 }
 
@@ -143,6 +183,7 @@ func init() {
 	proto.RegisterType((*VPNInitRequest)(nil), "pb.VPNInitRequest")
 	proto.RegisterType((*VPNStatusResponse)(nil), "pb.VPNStatusResponse")
 	proto.RegisterType((*VPNInitResponse)(nil), "pb.VPNInitResponse")
+	proto.RegisterEnum("pb.VPNProto", VPNProto_name, VPNProto_value)
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -253,27 +294,31 @@ var _VPNService_serviceDesc = grpc.ServiceDesc{
 func init() { proto.RegisterFile("vpn.proto", fileDescriptor1) }
 
 var fileDescriptor1 = []byte{
-	// 341 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcd, 0x4e, 0xfa, 0x40,
-	0x14, 0xc5, 0x53, 0xe0, 0xdf, 0x3f, 0xbd, 0x21, 0x08, 0x17, 0x3f, 0x6a, 0xc3, 0xc2, 0xcc, 0xca,
-	0xb0, 0xa0, 0x51, 0x77, 0xac, 0x24, 0x6c, 0x70, 0x61, 0xd3, 0x40, 0xc2, 0x7e, 0xaa, 0x13, 0xd2,
-	0x08, 0x33, 0xb5, 0x73, 0xe9, 0x03, 0xf8, 0x0a, 0xbe, 0x84, 0xef, 0xe3, 0x2b, 0xb8, 0xf3, 0x25,
-	0xcc, 0x4c, 0x2b, 0x5f, 0x89, 0xbb, 0x33, 0xbf, 0xb9, 0xf7, 0x9c, 0xf4, 0x74, 0xc0, 0x2b, 0x32,
-	0x39, 0xcc, 0x72, 0x45, 0x0a, 0x6b, 0x59, 0x12, 0xf4, 0x97, 0x4a, 0x2d, 0x57, 0x22, 0xe4, 0x59,
-	0x1a, 0x72, 0x29, 0x15, 0x71, 0x4a, 0x95, 0xd4, 0xe5, 0x04, 0x43, 0xe8, 0x2c, 0xe2, 0x68, 0x4e,
-	0x9c, 0x36, 0x7a, 0x26, 0x5e, 0x37, 0x42, 0x13, 0xbb, 0x87, 0xf6, 0x22, 0x8e, 0x1e, 0x64, 0x4a,
-	0x15, 0xc1, 0x00, 0x9a, 0x53, 0xa5, 0x49, 0xf2, 0xb5, 0xf0, 0x9d, 0x2b, 0xe7, 0xda, 0x9b, 0x6d,
-	0xcf, 0x88, 0xd0, 0x88, 0x55, 0x4e, 0x7e, 0xcd, 0x72, 0xab, 0xd9, 0xb7, 0x03, 0xdd, 0x3d, 0x5b,
-	0x9d, 0x29, 0xa9, 0xed, 0x64, 0xb4, 0x73, 0xb0, 0x1a, 0x19, 0xb4, 0xe6, 0x22, 0x4f, 0xf9, 0x2a,
-	0xda, 0xac, 0x13, 0x91, 0x57, 0x2e, 0x07, 0xec, 0x20, 0xbd, 0xfe, 0x47, 0x7a, 0x63, 0x97, 0x6e,
-	0xd8, 0x44, 0xe4, 0xe4, 0xff, 0x2b, 0x99, 0xd1, 0x78, 0x0e, 0xee, 0x64, 0x6c, 0xa9, 0x6b, 0x69,
-	0x75, 0xc2, 0x0e, 0xd4, 0x23, 0x41, 0xfe, 0x7f, 0x0b, 0x8d, 0x34, 0xdb, 0x8f, 0x5c, 0xbf, 0xf8,
-	0xcd, 0x72, 0xdb, 0x68, 0xec, 0x83, 0x37, 0xc9, 0x05, 0x27, 0xf1, 0x3c, 0x26, 0xdf, 0xb3, 0x17,
-	0x3b, 0xc0, 0xba, 0x70, 0xb2, 0xed, 0xab, 0xfc, 0xd4, 0xdb, 0x0f, 0x07, 0xc0, 0x14, 0x20, 0xf2,
-	0x22, 0x7d, 0x12, 0x18, 0x83, 0x5b, 0x76, 0x81, 0xa7, 0xc3, 0x2c, 0x19, 0x1e, 0x37, 0x1e, 0x9c,
-	0x1d, 0xd1, 0xd2, 0x85, 0x5d, 0xbe, 0x7d, 0x7e, 0xbd, 0xd7, 0x7a, 0xac, 0x1d, 0x16, 0x37, 0x61,
-	0x91, 0xc9, 0x50, 0xdb, 0xfb, 0x91, 0x33, 0xc0, 0x29, 0x34, 0x4c, 0x20, 0x62, 0xb5, 0xb9, 0xf7,
-	0xb7, 0x82, 0xde, 0x01, 0xab, 0xbc, 0x2e, 0xac, 0x57, 0x97, 0xb5, 0x7e, 0xbd, 0x52, 0x99, 0xd2,
-	0xc8, 0x19, 0x24, 0xae, 0x7d, 0x08, 0x77, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x17, 0xd3, 0x4c,
-	0xab, 0x37, 0x02, 0x00, 0x00,
+	// 406 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x72, 0xd3, 0x30,
+	0x10, 0x86, 0xb1, 0x93, 0xba, 0xf1, 0x4e, 0x26, 0x38, 0xdb, 0x02, 0x22, 0xd3, 0x43, 0x47, 0xa7,
+	0x4c, 0x0e, 0xf1, 0x50, 0x6e, 0xbd, 0x75, 0x0c, 0x4c, 0x39, 0x60, 0x34, 0x2e, 0xe4, 0x2e, 0x83,
+	0xe8, 0x78, 0x48, 0x25, 0x21, 0x29, 0xbe, 0xc3, 0x2b, 0xf0, 0x12, 0xbc, 0x0f, 0xaf, 0xc0, 0x83,
+	0x30, 0x92, 0xdd, 0x26, 0x66, 0x86, 0xdb, 0xbf, 0xdf, 0x66, 0x77, 0xff, 0xfc, 0x16, 0xa4, 0xad,
+	0x96, 0x6b, 0x6d, 0x94, 0x53, 0x18, 0xeb, 0x7a, 0x71, 0x76, 0xab, 0xd4, 0xed, 0x56, 0xe4, 0x5c,
+	0x37, 0x39, 0x97, 0x52, 0x39, 0xee, 0x1a, 0x25, 0x6d, 0xf7, 0x0b, 0x8a, 0x90, 0x6d, 0x58, 0x79,
+	0xe3, 0xb8, 0xdb, 0xd9, 0x4a, 0x7c, 0xdb, 0x09, 0xeb, 0xe8, 0x16, 0x66, 0x1b, 0x56, 0xbe, 0x95,
+	0x8d, 0xeb, 0x09, 0x2e, 0x60, 0x72, 0xad, 0xac, 0x93, 0xfc, 0x4e, 0x90, 0xe8, 0x3c, 0x5a, 0xa6,
+	0xd5, 0x43, 0x8d, 0x08, 0x63, 0xa6, 0x8c, 0x23, 0x71, 0xe0, 0x41, 0xe3, 0x0a, 0x52, 0xe6, 0xd7,
+	0x6b, 0x23, 0xbe, 0x90, 0xd1, 0x79, 0xb4, 0x9c, 0x5d, 0x4c, 0xd7, 0xba, 0x5e, 0x6f, 0x58, 0x19,
+	0x78, 0xb5, 0x6f, 0xd3, 0xef, 0x31, 0xcc, 0x0f, 0x2c, 0x58, 0xad, 0xa4, 0x0d, 0x5b, 0xcb, 0xfd,
+	0xb5, 0xa0, 0x91, 0xc2, 0xf4, 0x46, 0x98, 0x86, 0x6f, 0xcb, 0xdd, 0x5d, 0x2d, 0x4c, 0x7f, 0x71,
+	0xc0, 0x06, 0x4e, 0x47, 0xff, 0x71, 0x3a, 0x3e, 0x70, 0x8a, 0x30, 0x2e, 0x84, 0x71, 0xe4, 0xa8,
+	0x63, 0x5e, 0xe3, 0x53, 0x48, 0x8a, 0xab, 0x40, 0x93, 0x40, 0xfb, 0x0a, 0x33, 0x18, 0x95, 0xc2,
+	0x91, 0xe3, 0x00, 0xbd, 0xf4, 0xd3, 0xef, 0xb8, 0xfd, 0x4a, 0x26, 0xdd, 0xb4, 0xd7, 0x78, 0x06,
+	0x69, 0x61, 0x04, 0x77, 0xe2, 0xf3, 0x95, 0x23, 0x69, 0x68, 0xec, 0x01, 0x9e, 0xc2, 0x51, 0xf8,
+	0xeb, 0x04, 0x42, 0xa7, 0x2b, 0xe8, 0x1c, 0x1e, 0x3f, 0x24, 0xde, 0x05, 0xb0, 0x5a, 0xc2, 0xe4,
+	0x3e, 0x2d, 0x04, 0x48, 0xca, 0xf7, 0xac, 0x7a, 0xfd, 0x26, 0x7b, 0x84, 0xc7, 0x30, 0xfa, 0xf8,
+	0x8a, 0x65, 0x91, 0x17, 0x1f, 0x0a, 0x96, 0xc5, 0x17, 0xbf, 0x22, 0x00, 0x1f, 0xa0, 0x30, 0x6d,
+	0xf3, 0x49, 0x20, 0x83, 0xa4, 0xcb, 0x12, 0x4f, 0xfb, 0xc8, 0x07, 0x5f, 0x77, 0xf1, 0xe4, 0x1f,
+	0xda, 0xdd, 0xa3, 0xcf, 0x7f, 0xfc, 0xfe, 0xf3, 0x33, 0x3e, 0xa1, 0xb3, 0xbc, 0x7d, 0x91, 0xb7,
+	0x5a, 0xe6, 0x36, 0xf4, 0x2f, 0xa3, 0x15, 0x5e, 0xc3, 0xd8, 0x5b, 0x43, 0xec, 0x27, 0x0f, 0x5e,
+	0xc6, 0xe2, 0x64, 0xc0, 0xfa, 0x5d, 0xcf, 0xc2, 0xae, 0x39, 0x9d, 0xde, 0xef, 0x6a, 0x64, 0xe3,
+	0x2e, 0xa3, 0x55, 0x9d, 0x84, 0x47, 0xf7, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x94,
+	0xe6, 0xba, 0xa3, 0x02, 0x00, 0x00,
 }

+ 8 - 0
pb/vpn.proto

@@ -4,10 +4,17 @@ package pb;
 
 import "google/api/annotations.proto";
 
+enum VPNProto {
+  NOPREF = 0;
+  UDP = 1;
+  TCP = 2;
+}
+
 message VPNStatusRequest {}
 message VPNInitRequest {
   string Hostname = 1;
   string Port = 2;
+  VPNProto Protopref = 3;
 }
 
 service VPNService {
@@ -33,5 +40,6 @@ message VPNStatusResponse {
   string Net = 7;
   string Mask = 8;
   string CreatedAt = 9;
+  string Proto = 10;
 }
 message VPNInitResponse {}

+ 15 - 0
pb/vpn.swagger.json

@@ -77,12 +77,24 @@
         },
         "Port": {
           "type": "string"
+        },
+        "Protopref": {
+          "$ref": "#/definitions/pbVPNProto"
         }
       }
     },
     "pbVPNInitResponse": {
       "type": "object"
     },
+    "pbVPNProto": {
+      "type": "string",
+      "enum": [
+        "NOPREF",
+        "UDP",
+        "TCP"
+      ],
+      "default": "NOPREF"
+    },
     "pbVPNStatusRequest": {
       "type": "object"
     },
@@ -115,6 +127,9 @@
         },
         "CreatedAt": {
           "type": "string"
+        },
+        "Proto": {
+          "type": "string"
         }
       }
     }

+ 1 - 1
template/server.conf.tmpl

@@ -3,7 +3,7 @@ port {{ .Port }}
 
 # TCP or UDP server?
 ;proto tcp
-proto udp
+proto {{ .Proto }}
 
 # "dev tun" will create a routed IP tunnel,
 # "dev tap" will create an ethernet tunnel.

+ 10 - 11
user_test.go

@@ -13,7 +13,7 @@ func TestCreateNewUser(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 	server, _ := ovpm.GetServerInstance()
 
 	// Prepare:
@@ -81,7 +81,7 @@ func TestUserUpdate(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 	username := "testUser"
@@ -117,7 +117,7 @@ func TestUserPasswordCorrect(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 	initialPassword := "g00dp@ssW0rd9"
@@ -134,7 +134,7 @@ func TestUserPasswordReset(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 	initialPassword := "g00dp@ssW0rd9"
@@ -161,7 +161,7 @@ func TestUserDelete(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 	username := "testUser"
@@ -199,7 +199,7 @@ func TestUserGet(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 	username := "testUser"
@@ -223,7 +223,7 @@ func TestUserGetAll(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 	count := 5
 
 	// Prepare:
@@ -261,14 +261,14 @@ func TestUserRenew(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 	user, _ := ovpm.CreateNewUser("user", "1234", false, 0)
 
 	// Test:
 	// Re initialize the server.
-	ovpm.Init("example.com", "3333") // This causes implicit Renew() on every user in the system.
+	ovpm.Init("example.com", "3333", ovpm.UDPProto) // This causes implicit Renew() on every user in the system.
 
 	// Fetch user back.
 	fetchedUser, _ := ovpm.GetUser(user.GetUsername())
@@ -283,7 +283,7 @@ func TestUserIPAllocator(t *testing.T) {
 	// Initialize:
 	ovpm.SetupDB("sqlite3", ":memory:")
 	defer ovpm.CeaseDB()
-	ovpm.Init("localhost", "")
+	ovpm.Init("localhost", "", ovpm.UDPProto)
 
 	// Prepare:
 
@@ -336,7 +336,6 @@ func areUsersEqual(user1, user2 *ovpm.DBUser) bool {
 	}
 	logrus.Infof("users are the same!")
 	return true
-
 }
 
 func init() {

+ 23 - 1
vpn.go

@@ -27,6 +27,11 @@ import (
 	"github.com/jinzhu/gorm"
 )
 
+const (
+	TCPProto string = "tcp"
+	UDPProto string = "udp"
+)
+
 // DBServer is database model for storing VPN server related stuff.
 type DBServer struct {
 	gorm.Model
@@ -35,6 +40,7 @@ type DBServer struct {
 
 	Hostname string // Server's ip address or FQDN
 	Port     string // Server's listening port
+	Proto    string // Server's proto udp or tcp
 	Cert     string // Server RSA certificate.
 	Key      string // Server RSA private key.
 	CACert   string // Root CA RSA certificate.
@@ -60,14 +66,28 @@ type _VPNServerConfig struct {
 	Net          string
 	Mask         string
 	Port         string
+	Proto        string
 }
 
 // Init regenerates keys and certs for a Root CA, and saves them in the database.
-func Init(hostname string, port string) error {
+//
+// proto can be either "udp" or "tcp" and if it's "" it defaults to "udp".
+func Init(hostname string, port string, proto string) error {
 	if port == "" {
 		port = DefaultVPNPort
 	}
 
+	switch proto {
+	case "":
+		proto = UDPProto
+	case UDPProto:
+		proto = UDPProto
+	case TCPProto:
+		proto = TCPProto
+	default:
+		return fmt.Errorf("validation error: proto:`%s` should be either 'tcp' or 'udp'", proto)
+	}
+
 	if !govalidator.IsNumeric(port) {
 		return fmt.Errorf("validation error: port:`%s` should be numeric", port)
 	}
@@ -99,6 +119,7 @@ func Init(hostname string, port string) error {
 
 		SerialNumber: serialNumber,
 		Hostname:     hostname,
+		Proto:        proto,
 		Port:         port,
 		Cert:         srv.Cert,
 		Key:          srv.Key,
@@ -376,6 +397,7 @@ func emitServerConf() error {
 		Net:          _DefaultServerNetwork,
 		Mask:         _DefaultServerNetMask,
 		Port:         port,
+		Proto:        serverInstance.Proto,
 	}
 	data, err := bindata.Asset("template/server.conf.tmpl")
 	if err != nil {

+ 12 - 12
vpn_test.go

@@ -35,13 +35,13 @@ func TestVPNInit(t *testing.T) {
 	}
 
 	// Wrongfully initialize server.
-	err := Init("localhost", "asdf")
+	err := Init("localhost", "asdf", UDPProto)
 	if err == nil {
 		t.Fatalf("error is expected to be not nil but it's nil instead")
 	}
 
 	// Initialize the server.
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Check database if the database has no server.
 	var server2 DBServer
@@ -61,7 +61,7 @@ func TestVPNDeinit(t *testing.T) {
 
 	// Prepare:
 	// Initialize the server.
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 	u, err := CreateNewUser("user", "p", false, 0)
 	if err != nil {
 		t.Fatal(err)
@@ -122,7 +122,7 @@ func TestVPNIsInitialized(t *testing.T) {
 	}
 
 	// Initialize the server.
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Isn't initialized?
 	if !IsInitialized() {
@@ -152,7 +152,7 @@ func TestVPNGetServerInstance(t *testing.T) {
 	}
 
 	// Initialize server.
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	server, err = GetServerInstance()
 
@@ -172,7 +172,7 @@ func TestVPNDumpsClientConfig(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	user, _ := CreateNewUser("user", "password", false, 0)
@@ -194,7 +194,7 @@ func TestVPNDumpClientConfig(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	noGW := false
@@ -262,7 +262,7 @@ func TestVPNGetSystemCA(t *testing.T) {
 	}
 
 	// Initialize system.
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	ca, err = GetSystemCA()
 	if err != nil {
@@ -302,7 +302,7 @@ func TestVPNStartVPNProc(t *testing.T) {
 	}
 
 	// Initialize OVPM server.
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Call start again..
 	StartVPNProc()
@@ -318,7 +318,7 @@ func TestVPNStopVPNProc(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 	vpnProc.Start()
@@ -342,7 +342,7 @@ func TestVPNRestartVPNProc(t *testing.T) {
 	// Init:
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 
@@ -371,7 +371,7 @@ func TestVPNEmit(t *testing.T) {
 	setupTestCase()
 	SetupDB("sqlite3", ":memory:")
 	defer CeaseDB()
-	Init("localhost", "")
+	Init("localhost", "", UDPProto)
 
 	// Prepare:
 

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů