mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Agnhost: make it possible to pass the addresses to listen on for udp
The current udp implementation listens on any for tcp, udp and tcp. There are some cases where it makes sense to listen on specific addresses (especially udp, see https://github.com/kubernetes/kubernetes/issues/95565). This is because UDP is connectionless, and in order to conntrack to work, the application must ensure that the src of the reply is the same as the dest of the request. The easiest way to do that is to bind explicitly on an ip. Here we pass an optional parameter that contains a comma separated list of addresses. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
This commit is contained in:
parent
66cbf0196b
commit
5125f1fc31
@ -37,19 +37,23 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
var (
|
||||
httpPort = 8080
|
||||
udpPort = 8081
|
||||
sctpPort = -1
|
||||
shellPath = "/bin/sh"
|
||||
serverReady = &atomicBool{0}
|
||||
certFile = ""
|
||||
privKeyFile = ""
|
||||
httpOverride = ""
|
||||
httpPort = 8080
|
||||
udpPort = 8081
|
||||
sctpPort = -1
|
||||
shellPath = "/bin/sh"
|
||||
serverReady = &atomicBool{0}
|
||||
certFile = ""
|
||||
privKeyFile = ""
|
||||
httpOverride = ""
|
||||
udpListenAddresses = ""
|
||||
)
|
||||
|
||||
const bindToAny = ""
|
||||
|
||||
// CmdNetexec is used by agnhost Cobra.
|
||||
var CmdNetexec = &cobra.Command{
|
||||
Use: "netexec",
|
||||
@ -123,6 +127,7 @@ func init() {
|
||||
CmdNetexec.Flags().IntVar(&udpPort, "udp-port", 8081, "UDP Listen Port")
|
||||
CmdNetexec.Flags().IntVar(&sctpPort, "sctp-port", -1, "SCTP Listen Port")
|
||||
CmdNetexec.Flags().StringVar(&httpOverride, "http-override", "", "Override the HTTP handler to always respond as if it were a GET with this path & params")
|
||||
CmdNetexec.Flags().StringVar(&udpListenAddresses, "udp-listen-addresses", "", "A comma separated list of ip addresses the udp servers listen from")
|
||||
}
|
||||
|
||||
// atomicBool uses load/store operations on an int32 to simulate an atomic boolean.
|
||||
@ -162,7 +167,14 @@ func main(cmd *cobra.Command, args []string) {
|
||||
addRoutes(http.DefaultServeMux, exitCh)
|
||||
}
|
||||
|
||||
go startUDPServer(udpPort)
|
||||
udpBindTo, err := parseAddresses(udpListenAddresses)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, address := range udpBindTo {
|
||||
go startUDPServer(address, udpPort)
|
||||
}
|
||||
if sctpPort != -1 {
|
||||
go startSCTPServer(sctpPort)
|
||||
}
|
||||
@ -539,15 +551,15 @@ func redirectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// udp server supports the hostName, echo and clientIP commands.
|
||||
func startUDPServer(udpPort int) {
|
||||
serverAddress, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", udpPort))
|
||||
func startUDPServer(address string, udpPort int) {
|
||||
serverAddress, err := net.ResolveUDPAddr("udp", net.JoinHostPort(address, strconv.Itoa(udpPort)))
|
||||
assertNoError(err, fmt.Sprintf("failed to resolve UDP address for port %d", sctpPort))
|
||||
serverConn, err := net.ListenUDP("udp", serverAddress)
|
||||
assertNoError(err, fmt.Sprintf("failed to create listener for UDP address %v", serverAddress))
|
||||
defer serverConn.Close()
|
||||
buf := make([]byte, 2048)
|
||||
|
||||
log.Printf("Started UDP server on port %d", udpPort)
|
||||
log.Printf("Started UDP server on port %s %d", address, udpPort)
|
||||
// Start responding to readiness probes.
|
||||
serverReady.set(true)
|
||||
defer func() {
|
||||
@ -639,3 +651,21 @@ func assertNoError(err error, detail string) {
|
||||
log.Fatalf("Error occurred: %s:%v", detail, err)
|
||||
}
|
||||
}
|
||||
|
||||
func parseAddresses(addresses string) ([]string, error) {
|
||||
if addresses == "" {
|
||||
return []string{bindToAny}, nil
|
||||
}
|
||||
// Using a set to remove duplicates
|
||||
res := make([]string, 0)
|
||||
split := strings.Split(addresses, ",")
|
||||
for _, address := range split {
|
||||
netAddr := net.ParseIP(address)
|
||||
if netAddr == nil {
|
||||
return nil, fmt.Errorf("parseAddress: invalid address %s", address)
|
||||
}
|
||||
res = append(res, address)
|
||||
}
|
||||
set := sets.NewString(res...)
|
||||
return set.List(), nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user