parse and handle config; put Apache 2.0 License

This commit is contained in:
2025-04-19 11:23:23 +10:00
parent 57385cbaed
commit d0b3cbf967
12 changed files with 574 additions and 12 deletions

View File

@@ -1,15 +1,40 @@
package config
/*
Copyright 2025 Suyono <suyono3484@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"fmt"
"gitea.suyono.dev/suyono/netbounce/abstract"
"maps"
"slices"
"github.com/spf13/viper"
)
const (
CONNECTION = "connection"
TYPE = "type"
UDP = "udp"
TCP = "tcp"
)
func ReadConfig() error {
viper.SetDefault("config", "/etc/netbounce/netbounce.yml")
configPath := viper.GetString("config")
if configPath == "" {
return fmt.Errorf("config file path is empty")
}
viper.SetConfigFile(configPath)
viper.SetConfigType("yaml")
@@ -18,3 +43,48 @@ func ReadConfig() error {
}
return nil
}
func ListConnection() ([]string, error) {
m := viper.GetStringMap(CONNECTION)
l := slices.Collect(maps.Keys(m))
if len(l) == 0 {
return nil, fmt.Errorf("no connection found")
}
return l, nil
}
func GetConnection(name string) (abstract.ConnectionConfig, error) {
var (
tcp tcpConfig
udp udpConfig
err error
)
configType := viper.GetString(fmt.Sprintf("%s.%s.%s", CONNECTION, name, TYPE))
if configType == "" {
return nil, fmt.Errorf("no connection found")
}
configKey := fmt.Sprintf("%s.%s", CONNECTION, name)
switch configType {
case UDP:
if err = viper.UnmarshalKey(configKey, &udp); err != nil {
return nil, fmt.Errorf("unmarshal config %s: %w", configKey, err)
}
udp.Name = name
udp.Type = abstract.UDP
return udpModule{config: udp}, nil
case TCP:
if err = viper.UnmarshalKey(configKey, &tcp); err != nil {
return nil, fmt.Errorf("unmarshal config %s: %w", configKey, err)
}
tcp.Name = name
tcp.Type = abstract.TCP
return tcpModule{config: tcp}, nil
default:
return nil, fmt.Errorf("connection %s: invalid connection type: %s", name, configType)
}
}

View File

@@ -1,8 +1,28 @@
package config
import "github.com/spf13/viper"
/*
Copyright 2025 Suyono <suyono3484@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
func CollectEnv() {
viper.SetEnvPrefix("NETBOUNCE_")
_ = viper.BindEnv("config", "CONFIG")
if err := viper.BindEnv("config", "NETBOUNCE_CONFIG"); err != nil {
log.Warn().Err(err).Msg("failed to bind env for config")
}
}

63
config/tcp.go Normal file
View File

@@ -0,0 +1,63 @@
package config
/*
Copyright 2025 Suyono <suyono3484@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"fmt"
"gitea.suyono.dev/suyono/netbounce/abstract"
)
type tcpConfig struct {
Name string `mapstructure:"-,"`
Type abstract.ConnectionType `mapstructure:"-,"`
Listen string `mapstructure:"listen"`
Backend string `mapstructure:"backend"`
KeepAlive bool `mapstructure:"keepalive,false"`
}
type tcpModule struct {
config tcpConfig
}
func (t tcpModule) Name() string {
return t.config.Name
}
func (t tcpModule) Type() abstract.ConnectionType {
return t.config.Type
}
func (t tcpModule) Listen() string {
return t.config.Listen
}
func (t tcpModule) Backend() string {
return t.config.Backend
}
func (t tcpModule) KeepAlive() bool {
return t.config.KeepAlive
}
func (t tcpModule) AsTCP() abstract.TCPConnectionConfig {
return t
}
func (t tcpModule) AsUDP() abstract.UDPConnectionConfig {
panic(fmt.Errorf("not UDP"))
return nil
}

64
config/udp.go Normal file
View File

@@ -0,0 +1,64 @@
package config
/*
Copyright 2025 Suyono <suyono3484@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"fmt"
"gitea.suyono.dev/suyono/netbounce/abstract"
"time"
)
type udpConfig struct {
Name string `mapstructure:"-,"`
Type abstract.ConnectionType `mapstructure:"-,"`
Listen string `mapstructure:"listen"`
Backend string `mapstructure:"backend"`
Timeout time.Duration `mapstructure:"timeout,30m"`
}
type udpModule struct {
config udpConfig
}
func (u udpModule) AsUDP() abstract.UDPConnectionConfig {
return u
}
func (u udpModule) AsTCP() abstract.TCPConnectionConfig {
panic(fmt.Errorf("not UDP"))
return nil
}
func (u udpModule) Name() string {
return u.config.Name
}
func (u udpModule) Type() abstract.ConnectionType {
return u.config.Type
}
func (u udpModule) Listen() string {
return u.config.Listen
}
func (u udpModule) Backend() string {
return u.config.Backend
}
func (u udpModule) Timeout() time.Duration {
return u.config.Timeout
}