mirror of https://github.com/fatedier/frp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
2.4 KiB
107 lines
2.4 KiB
// Copyright 2023 The frp Authors |
|
// |
|
// 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. |
|
|
|
package virtual |
|
|
|
import ( |
|
"context" |
|
"net" |
|
|
|
"github.com/fatedier/frp/client" |
|
v1 "github.com/fatedier/frp/pkg/config/v1" |
|
"github.com/fatedier/frp/pkg/msg" |
|
netpkg "github.com/fatedier/frp/pkg/util/net" |
|
) |
|
|
|
type ClientOptions struct { |
|
Common *v1.ClientCommonConfig |
|
Spec *msg.ClientSpec |
|
HandleWorkConnCb func(*v1.ProxyBaseConfig, net.Conn, *msg.StartWorkConn) bool |
|
} |
|
|
|
type Client struct { |
|
l *netpkg.InternalListener |
|
svr *client.Service |
|
} |
|
|
|
func NewClient(options ClientOptions) (*Client, error) { |
|
if options.Common != nil { |
|
options.Common.Complete() |
|
} |
|
|
|
ln := netpkg.NewInternalListener() |
|
|
|
serviceOptions := client.ServiceOptions{ |
|
Common: options.Common, |
|
ClientSpec: options.Spec, |
|
ConnectorCreator: func(context.Context, *v1.ClientCommonConfig) client.Connector { |
|
return &pipeConnector{ |
|
peerListener: ln, |
|
} |
|
}, |
|
HandleWorkConnCb: options.HandleWorkConnCb, |
|
} |
|
svr, err := client.NewService(serviceOptions) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return &Client{ |
|
l: ln, |
|
svr: svr, |
|
}, nil |
|
} |
|
|
|
func (c *Client) PeerListener() net.Listener { |
|
return c.l |
|
} |
|
|
|
func (c *Client) UpdateProxyConfigurer(proxyCfgs []v1.ProxyConfigurer) { |
|
_ = c.svr.UpdateAllConfigurer(proxyCfgs, nil) |
|
} |
|
|
|
func (c *Client) Run(ctx context.Context) error { |
|
return c.svr.Run(ctx) |
|
} |
|
|
|
func (c *Client) Service() *client.Service { |
|
return c.svr |
|
} |
|
|
|
func (c *Client) Close() { |
|
c.svr.Close() |
|
c.l.Close() |
|
} |
|
|
|
type pipeConnector struct { |
|
peerListener *netpkg.InternalListener |
|
} |
|
|
|
func (pc *pipeConnector) Open() error { |
|
return nil |
|
} |
|
|
|
func (pc *pipeConnector) Connect() (net.Conn, error) { |
|
c1, c2 := net.Pipe() |
|
if err := pc.peerListener.PutConn(c1); err != nil { |
|
c1.Close() |
|
c2.Close() |
|
return nil, err |
|
} |
|
return c2, nil |
|
} |
|
|
|
func (pc *pipeConnector) Close() error { |
|
pc.peerListener.Close() |
|
return nil |
|
}
|
|
|