mirror of
https://github.com/bolucat/Archive.git
synced 2025-09-27 04:30:12 +08:00
112 lines
3.7 KiB
Go
112 lines
3.7 KiB
Go
// Copyright (C) 2024 mieru authors
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package client
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
|
|
apicommon "github.com/enfein/mieru/v3/apis/common"
|
|
"github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
|
|
)
|
|
|
|
var (
|
|
ErrNoClientConfig = errors.New("no client config")
|
|
ErrInvalidClientConfig = errors.New("invalid client config")
|
|
ErrClientIsNotRunning = errors.New("client is not running")
|
|
ErrStoreClientConfigAfterStart = errors.New("can't store client config after start")
|
|
)
|
|
|
|
// Client contains methods supported by a proxy client.
|
|
type Client interface {
|
|
ClientConfigurationService
|
|
ClientLifecycleService
|
|
ClientNetworkService
|
|
}
|
|
|
|
// ClientConfigurationService contains methods to manage proxy client configuration.
|
|
type ClientConfigurationService interface {
|
|
// Load returns the client config.
|
|
// It returns ErrNoClientConfig if client config is never stored.
|
|
Load() (*ClientConfig, error)
|
|
|
|
// Store saves the client config.
|
|
// It returns wrapped ErrInvalidConfigConfig error
|
|
// if the provided client config is invalid.
|
|
// It returns ErrStoreClientConfigAfterStart error
|
|
// if it is called after start.
|
|
Store(*ClientConfig) error
|
|
}
|
|
|
|
// ClientLifecycleService contains methods to manage proxy client lifecycle.
|
|
type ClientLifecycleService interface {
|
|
// Start activates the client with the stored configuration.
|
|
// Calling Start function more than once has undefined behavior.
|
|
Start() error
|
|
|
|
// Stop deactivates the client.
|
|
// Established network connections are NOT terminated.
|
|
// After stop, the client can't be reused.
|
|
Stop() error
|
|
|
|
// IsRunning returns true if the client has been started
|
|
// and has not been stopped.
|
|
IsRunning() bool
|
|
}
|
|
|
|
// ClientNetworkService contains methods to establish connections
|
|
// to destinations using proxy servers.
|
|
type ClientNetworkService interface {
|
|
// DialContext returns a new proxy connection to reach the destination.
|
|
// It uses the dialer in ClientConfig to connect to a proxy server endpoint.
|
|
//
|
|
// If HandshakeMode in ClientConfig is HANDSHAKE_NO_WAIT, handshake is performed
|
|
// upon the first write to the network connection. Otherwise, handshake is
|
|
// performed before this method returns.
|
|
//
|
|
// This is a streaming based proxy connection. If the destination is a packet
|
|
// endpoint, packets are encapsulated in the streaming connection.
|
|
//
|
|
// It returns an error if the client has not been started,
|
|
// or has been stopped.
|
|
DialContext(context.Context, net.Addr) (net.Conn, error)
|
|
}
|
|
|
|
// ClientConfig stores proxy client configuration.
|
|
type ClientConfig struct {
|
|
// Main configuration.
|
|
Profile *appctlpb.ClientProfile
|
|
|
|
// A dialer to connect to proxy server via stream-oriented network connections.
|
|
//
|
|
// If this field is not set, a default dialer is used.
|
|
Dialer apicommon.Dialer
|
|
|
|
// If set, the resolver translates proxy server domain name into IP addresses.
|
|
//
|
|
// This field is not required, if Dialer is able to do DNS, or proxy server
|
|
// endpoints are IP addresses rather than domain names.
|
|
Resolver apicommon.DNSResolver
|
|
}
|
|
|
|
// NewClient creates a blank mieru client with no client config.
|
|
func NewClient() Client {
|
|
mc := &mieruClient{}
|
|
mc.initOnce()
|
|
return mc
|
|
}
|