Compare commits
2 Commits
main
...
Xe/tsnet-f
Author | SHA1 | Date |
---|---|---|
![]() |
12720007ce | |
![]() |
ea86fc127a |
|
@ -574,6 +574,7 @@ func (pln *peerAPIListener) ServeConn(src netip.AddrPort, c net.Conn) {
|
|||
c.Close()
|
||||
return
|
||||
}
|
||||
logf("remoteAddr=%v", src)
|
||||
h := &peerAPIHandler{
|
||||
ps: pln.ps,
|
||||
isSelf: nm.SelfNode.User == peerNode.User,
|
||||
|
@ -1022,6 +1023,8 @@ func (h *peerAPIHandler) canIngress() bool {
|
|||
}
|
||||
|
||||
func (h *peerAPIHandler) peerHasCap(wantCap string) bool {
|
||||
h.logf("h.remoteAddr.Addr()=%v", h.remoteAddr.Addr())
|
||||
h.logf("h.ps.b.PeerCaps(h.remoteAddr.Addr())=%v", h.ps.b.PeerCaps(h.remoteAddr.Addr()))
|
||||
for _, hasCap := range h.ps.b.PeerCaps(h.remoteAddr.Addr()) {
|
||||
if hasCap == wantCap {
|
||||
return true
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// The tshello server demonstrates how to use Tailscale as a library.
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"tailscale.com/tsnet"
|
||||
)
|
||||
|
||||
var (
|
||||
addr = flag.String("addr", ":443", "address to listen on")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
s := new(tsnet.Server)
|
||||
defer s.Close()
|
||||
|
||||
publicLis, err := s.ExposeHTTPS()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ln, err := s.Listen("tcp", *addr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
lc, err := s.LocalClient()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ln = tls.NewListener(ln, &tls.Config{
|
||||
GetCertificate: lc.GetCertificate,
|
||||
})
|
||||
|
||||
go log.Fatal(http.Serve(publicLis, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "<html><body><h1>Hello, internet!</h1>")
|
||||
fmt.Fprintln(w, "<p>You are connected over the internet!</p></html>")
|
||||
})))
|
||||
log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "<html><body><h1>Hello, tailnet!</h1>")
|
||||
fmt.Fprintln(w, "<p>You are connected over the tailnet!</p></html>")
|
||||
})))
|
||||
}
|
|
@ -735,6 +735,90 @@ func (s *Server) APIClient() (*tailscale.Client, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
// ExposeHTTPS returns a HTTPS listener that is exposed over Funnel.
|
||||
// It will start the server if it has not been started yet.
|
||||
func (s *Server) ExposeHTTPS() (net.Listener, error) {
|
||||
if err := s.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp", "[::1]:42069")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
st := s.lb.StatusWithoutPeers()
|
||||
|
||||
for st.BackendState != "Running" {
|
||||
s.logf("waiting for control connection to set up exposed socket")
|
||||
time.Sleep(time.Second)
|
||||
st = s.lb.StatusWithoutPeers()
|
||||
}
|
||||
|
||||
if len(st.CertDomains) == 0 {
|
||||
return nil, errors.New("tsnet: you must enable HTTPS in the admin panel to proceed")
|
||||
}
|
||||
domain := st.CertDomains[0]
|
||||
|
||||
hp := ipn.HostPort(net.JoinHostPort(domain, "443"))
|
||||
|
||||
srvConfig := &ipn.ServeConfig{
|
||||
TCP: map[uint16]*ipn.TCPPortHandler{
|
||||
443: &ipn.TCPPortHandler{
|
||||
HTTPS: true,
|
||||
},
|
||||
},
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
hp: &ipn.WebServerConfig{
|
||||
Handlers: map[string]*ipn.HTTPHandler{
|
||||
"/": &ipn.HTTPHandler{Proxy: ln.Addr().String()},
|
||||
},
|
||||
},
|
||||
},
|
||||
AllowFunnel: map[ipn.HostPort]bool{
|
||||
hp: true,
|
||||
},
|
||||
}
|
||||
|
||||
if err := s.lb.SetServeConfig(srvConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &funnelListenerWrapper{ln, s}, nil
|
||||
}
|
||||
|
||||
type funnelListenerWrapper struct {
|
||||
net.Listener
|
||||
s *Server
|
||||
}
|
||||
|
||||
func (flw *funnelListenerWrapper) Accept() (net.Conn, error) {
|
||||
conn, err := flw.Listener.Accept()
|
||||
|
||||
flw.s.logf("got connection from %s", conn.RemoteAddr())
|
||||
|
||||
return conn, err
|
||||
}
|
||||
|
||||
func (flw *funnelListenerWrapper) Close() error {
|
||||
defer flw.Listener.Close()
|
||||
|
||||
lc, err := flw.s.LocalClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := lc.SetServeConfig(context.Background(), &ipn.ServeConfig{
|
||||
TCP: map[uint16]*ipn.TCPPortHandler{},
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{},
|
||||
AllowFunnel: map[ipn.HostPort]bool{},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Listen announces only on the Tailscale network.
|
||||
// It will start the server if it has not been started yet.
|
||||
func (s *Server) Listen(network, addr string) (net.Listener, error) {
|
||||
|
|
Loading…
Reference in New Issue