Projects STRLCPY cdebug Commits 49d253b4
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    cmd/portforward/portforward.go
    skipped 148 lines
    149 149   defer cancel()
    150 150   
    151 151   for {
    152  - cont, err := runLocalPortForward(ctx, cli, client, opts)
     152 + cont, err := runLocalPortForwarding(ctx, cli, client, opts)
    153 153   if err != nil {
    154 154   return err
    155 155   }
    skipped 6 lines
    162 162   }
    163 163  }
    164 164   
    165  -func runLocalPortForward(
     165 +func runLocalPortForwarding(
    166 166   ctx context.Context,
    167 167   cli cliutil.CLI,
    168 168   client dockerclient.CommonAPIClient,
    skipped 101 lines
    270 270   localPort string
    271 271   remoteHost string
    272 272   remotePort string
     273 +}
     274 + 
     275 +type directForwarding struct {
     276 + forwarding
     277 + targetNetwork string
     278 +}
     279 + 
     280 +type sidecarForwarding struct {
     281 + forwarding
     282 + targetID string // for netns
     283 + targetNetwork string
     284 + targetHost string
     285 + sidecarPort string
    273 286  }
    274 287   
    275 288  func parseLocalForwardings(
    skipped 179 lines
    455 468   for _, fwd := range locals {
    456 469   wg.Add(1)
    457 470   
    458  - go func() {
     471 + go func(fwd forwarding) {
    459 472   defer wg.Done()
    460 473   
    461 474   if err := runLocalForwarder(ctx, cli, client, target, fwd); err != nil {
    462 475   logrus.Debugf("Forwarding error: %s", err)
    463 476   errored = true
    464 477   }
    465  - }()
     478 + }(fwd)
    466 479   }
    467 480   
    468 481   wg.Wait()
    skipped 28 lines
    497 510   return err
    498 511   }
    499 512   
    500  - return runLocalForwarderDirect(
     513 + return runLocalDirectForwarder(
    501 514   ctx,
    502 515   cli,
    503 516   client,
    504  - network,
    505  - forwarding{
    506  - localHost: fwd.localHost,
    507  - localPort: fwd.localPort,
    508  - remoteHost: remoteIP,
    509  - remotePort: fwd.remotePort,
     517 + directForwarding{
     518 + targetNetwork: network,
     519 + forwarding: forwarding{
     520 + localHost: fwd.localHost,
     521 + localPort: fwd.localPort,
     522 + remoteHost: remoteIP,
     523 + remotePort: fwd.remotePort,
     524 + },
    510 525   },
    511 526   )
    512 527   }
    skipped 4 lines
    517 532   return err
    518 533   }
    519 534   
    520  - return runLocalForwarderDirect(
     535 + return runLocalDirectForwarder(
    521 536   ctx,
    522 537   cli,
    523 538   client,
    524  - network,
    525  - forwarding{
    526  - localHost: fwd.localHost,
    527  - localPort: fwd.localPort,
    528  - remoteHost: remoteIP,
    529  - remotePort: fwd.remotePort,
     539 + directForwarding{
     540 + targetNetwork: network,
     541 + forwarding: forwarding{
     542 + localHost: fwd.localHost,
     543 + localPort: fwd.localPort,
     544 + remoteHost: remoteIP,
     545 + remotePort: fwd.remotePort,
     546 + },
    530 547   },
    531 548   )
    532 549   }
    533 550   
    534  - return runLocalForwarderWithSidecar(ctx, cli, client, target, fwd)
     551 + // In a multi-network case, pick a random one.
     552 + var targetNetwork, targetIP string
     553 + for name, settings := range target.NetworkSettings.Networks {
     554 + if len(settings.IPAddress) > 0 {
     555 + targetNetwork = name
     556 + targetIP = settings.IPAddress
     557 + break
     558 + }
     559 + }
     560 + if len(targetNetwork) == 0 || len(targetIP) == 0 {
     561 + return errors.New("target is not attached to any networks")
     562 + }
     563 + 
     564 + return runLocalSidecarForwarder(
     565 + ctx,
     566 + cli,
     567 + client,
     568 + sidecarForwarding{
     569 + targetID: target.ID,
     570 + targetNetwork: targetNetwork,
     571 + targetHost: targetIP,
     572 + forwarding: fwd, // as is
     573 + },
     574 + )
    535 575  }
    536 576   
    537  -func runLocalForwarderDirect(
     577 +func runLocalDirectForwarder(
    538 578   ctx context.Context,
    539 579   cli cliutil.CLI,
    540 580   client dockerclient.CommonAPIClient,
    541  - network string,
    542  - fwd forwarding,
     581 + fwd directForwarding,
    543 582  ) error {
    544 583   // TODO: Try start() N times.
    545 584   
    546  - forwarderID, err := startLocalForwarder(ctx, client, network, fwd)
     585 + forwarderID, err := startLocalDirectForwarder(ctx, client, fwd)
    547 586   defer cleanupContainerIfExist(client, forwarderID)
    548 587   if err != nil {
    549 588   return fmt.Errorf("starting forwarder failed: %w", err)
    550 589   }
    551 590   
    552  - if err := printOutForwarding(ctx, cli, client, fwd, forwarderID, "", ""); err != nil {
     591 + if err := printLocalDirectForwarding(ctx, cli, client, fwd, forwarderID); err != nil {
    553 592   return err
    554 593   }
    555 594   
    skipped 21 lines
    577 616   }
    578 617  }
    579 618   
    580  -func startLocalForwarder(
     619 +func startLocalDirectForwarder(
    581 620   ctx context.Context,
    582 621   client dockerclient.CommonAPIClient,
    583  - network string,
    584  - fwd forwarding,
     622 + fwd directForwarding,
    585 623  ) (string, error) {
    586 624   portMapSpec := fwd.localHost + ":" + fwd.localPort + ":" + fwd.remotePort
    587 625   exposedPorts, portBindings, err := nat.ParsePortSpecs([]string{portMapSpec})
    skipped 15 lines
    603 641   },
    604 642   &container.HostConfig{
    605 643   PortBindings: portBindings,
    606  - NetworkMode: container.NetworkMode(network),
     644 + NetworkMode: container.NetworkMode(fwd.targetNetwork),
    607 645   },
    608 646   nil,
    609 647   nil,
    skipped 10 lines
    620 658   return resp.ID, nil
    621 659  }
    622 660   
    623  -func runLocalForwarderWithSidecar(
     661 +func runLocalSidecarForwarder(
    624 662   ctx context.Context,
    625 663   cli cliutil.CLI,
    626 664   client dockerclient.CommonAPIClient,
    627  - target types.ContainerJSON,
    628  - fwd forwarding,
     665 + fwd sidecarForwarding,
    629 666  ) error {
    630 667   // TODO: Try starting sidecar and forwarder N times.
    631 668   
    632  - // In a multi-network case, pick a random one.
    633  - var targetNetwork, targetIP string
    634  - for name, settings := range target.NetworkSettings.Networks {
    635  - if len(settings.IPAddress) > 0 {
    636  - targetNetwork = name
    637  - targetIP = settings.IPAddress
    638  - break
    639  - }
    640  - }
    641  - if len(targetIP) == 0 {
    642  - return errors.New("target is not attached to any networks")
    643  - }
    644  - 
    645  - sidecarID, targetPort, err := startLocalForwarderSidecar(
    646  - ctx, client, target.ID, fwd.remoteHost, fwd.remotePort,
     669 + sidecarID, sidecarPort, err := startLocalSidecarForwarder(
     670 + ctx, client, fwd.targetID, fwd.remoteHost, fwd.remotePort,
    647 671   )
    648 672   defer cleanupContainerIfExist(client, sidecarID)
    649 673   if err != nil {
    650 674   return fmt.Errorf("starting forwarder sidecar failed: %w", err)
    651 675   }
    652 676   
    653  - forwarderID, err := startLocalForwarder(
     677 + fwd.sidecarPort = sidecarPort // randomly chosen
     678 + 
     679 + forwarderID, err := startLocalDirectForwarder(
    654 680   ctx,
    655 681   client,
    656  - targetNetwork,
    657  - forwarding{
    658  - localHost: fwd.localHost,
    659  - localPort: fwd.localPort,
    660  - remoteHost: targetIP,
    661  - remotePort: fmt.Sprintf("%d", targetPort),
     682 + directForwarding{
     683 + targetNetwork: fwd.targetNetwork,
     684 + forwarding: forwarding{
     685 + localHost: fwd.localHost,
     686 + localPort: fwd.localPort,
     687 + remoteHost: fwd.targetHost,
     688 + remotePort: fwd.sidecarPort,
     689 + },
    662 690   },
    663 691   )
    664 692   defer cleanupContainerIfExist(client, forwarderID)
    skipped 1 lines
    666 694   return fmt.Errorf("starting forwarder faield: %w", err)
    667 695   }
    668 696   
    669  - if err := printOutForwarding(
    670  - ctx, cli, client, fwd, forwarderID, targetIP, fmt.Sprintf("%d", targetPort),
    671  - ); err != nil {
     697 + if err := printLocalSidecarForwarding(ctx, cli, client, fwd, forwarderID); err != nil {
    672 698   return err
    673 699   }
    674 700   
    skipped 37 lines
    712 738   }
    713 739  }
    714 740   
    715  -func startLocalForwarderSidecar(
     741 +func startLocalSidecarForwarder(
    716 742   ctx context.Context,
    717 743   client dockerclient.CommonAPIClient,
    718 744   targetID string,
    719 745   remoteHost string,
    720 746   remotePort string,
    721  -) (string, int, error) {
     747 +) (string, string, error) {
    722 748   // TODO: This random port may conflict with a port already used by the
    723 749   // target container. Instead, we should use socat TCP-LISTEN:0 and
    724 750   // detect what port was assigned by the OS with a separate command.
    725  - randomPort := 32000 + rand.Intn(25000)
     751 + randomPort := fmt.Sprintf("%d", 32000+rand.Intn(25000))
    726 752   resp, err := client.ContainerCreate(
    727 753   ctx,
    728 754   &container.Config{
    729 755   Image: forwarderImage,
    730 756   Entrypoint: []string{"socat"},
    731 757   Cmd: []string{
    732  - fmt.Sprintf("TCP4-LISTEN:%d,fork", randomPort),
     758 + fmt.Sprintf("TCP4-LISTEN:%s,fork", randomPort),
    733 759   fmt.Sprintf("TCP-CONNECT:%s:%s", remoteHost, remotePort),
    734 760   },
    735 761   Env: []string{"SOCAT_DEFAULT_LISTEN_IP=0.0.0.0"},
    skipped 6 lines
    742 768   "cdebug-fwd-sidecar-"+uuid.ShortID(),
    743 769   )
    744 770   if err != nil {
    745  - return "", 0, fmt.Errorf("cannot create forwarder sidecar container: %w", err)
     771 + return "", "", fmt.Errorf("cannot create forwarder sidecar container: %w", err)
    746 772   }
    747 773   
    748 774   if err := client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
    749  - return resp.ID, 0, fmt.Errorf("cannot start forwarder sidecar container: %w", err)
     775 + return resp.ID, "", fmt.Errorf("cannot start forwarder sidecar container: %w", err)
    750 776   }
    751 777   
    752 778   return resp.ID, randomPort, nil
    753 779  }
    754 780   
    755  -func printOutForwarding(
     781 +func printLocalDirectForwarding(
    756 782   ctx context.Context,
    757 783   cli cliutil.CLI,
    758 784   client dockerclient.CommonAPIClient,
    759  - fwd forwarding,
     785 + fwd directForwarding,
    760 786   forwarderID string,
    761  - proxyHost string,
    762  - proxyPort string,
    763 787  ) error {
    764 788   if len(fwd.localPort) == 0 {
    765 789   forwarder, err := client.ContainerInspect(ctx, forwarderID)
    skipped 11 lines
    777 801   }
    778 802   }
    779 803   
    780  - out := fmt.Sprintf(
    781  - "Forwarding %s:%s to %s:%s",
    782  - fwd.localHost, fwd.localPort, fwd.remoteHost, fwd.remotePort,
     804 + cli.PrintOut(
     805 + "Forwarding %s:%s to %s:%s\n",
     806 + fwd.localHost, fwd.localPort,
     807 + fwd.remoteHost, fwd.remotePort,
    783 808   )
    784  - if len(proxyHost) > 0 {
    785  - out += fmt.Sprintf(" through %s:%s", proxyHost, proxyPort)
     809 + 
     810 + return nil
     811 +}
     812 + 
     813 +func printLocalSidecarForwarding(
     814 + ctx context.Context,
     815 + cli cliutil.CLI,
     816 + client dockerclient.CommonAPIClient,
     817 + fwd sidecarForwarding,
     818 + forwarderID string,
     819 +) error {
     820 + if len(fwd.localPort) == 0 {
     821 + forwarder, err := client.ContainerInspect(ctx, forwarderID)
     822 + if err != nil {
     823 + return fmt.Errorf("cannot inspect forwarder container: %w", err)
     824 + }
     825 + 
     826 + bindings := lookupPortBindings(forwarder, fwd.sidecarPort)
     827 + if len(bindings) == 0 {
     828 + logrus.Debugf("Empty port bindings in forwarder %s", forwarder.ID)
     829 + fwd.localPort = "<unknown>"
     830 + } else {
     831 + // Every forwarder should have just one port exposed.
     832 + fwd.localPort = bindings[0].HostPort
     833 + }
    786 834   }
    787  - cli.PrintOut(out + "\n")
     835 + 
     836 + cli.PrintOut(
     837 + "Forwarding %s:%s to %s:%s through %s:%s\n",
     838 + fwd.localHost, fwd.localPort,
     839 + fwd.remoteHost, fwd.remotePort,
     840 + fwd.targetHost, fwd.sidecarPort,
     841 + )
    788 842   
    789 843   return nil
    790 844  }
    skipped 17 lines
Please wait...
Page is in error, reload to recover