Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package tcping for openSUSE:Factory checked in at 2023-03-06 18:55:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tcping (Old) and /work/SRC/openSUSE:Factory/.tcping.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tcping" Mon Mar 6 18:55:18 2023 rev:2 rq:1069492 version:1.19.1 Changes: -------- --- /work/SRC/openSUSE:Factory/tcping/tcping.changes 2022-11-16 15:43:45.535917787 +0100 +++ /work/SRC/openSUSE:Factory/.tcping.new.31432/tcping.changes 2023-03-06 18:55:20.360599801 +0100 @@ -1,0 +2,16 @@ +Sat Mar 4 16:52:49 UTC 2023 - Martin Hauke <mar...@gmx.de> + +- Update to version 1.19.1 + * close TCP connections faster to lessen the resource + utilization on target. + +------------------------------------------------------------------- +Sun Feb 26 13:33:47 UTC 2023 - Martin Hauke <mar...@gmx.de> + +- Update to version 1.19.0 + * implmenet sub-millisecond timing report to make it suitable + for Data center and Cloud environments. + * fix downtime report miscalculation. + * misc fixes + +------------------------------------------------------------------- Old: ---- tcping-1.12.1.tar.gz New: ---- tcping-1.19.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tcping.spec ++++++ --- /var/tmp/diff_new_pack.7lAGzr/_old 2023-03-06 18:55:21.052603332 +0100 +++ /var/tmp/diff_new_pack.7lAGzr/_new 2023-03-06 18:55:21.056603352 +0100 @@ -1,7 +1,8 @@ # # spec file for package tcping # -# Copyright (c) 2022, Martin Hauke <mar...@gmx.de> +# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2022-2023, Martin Hauke <mar...@gmx.de> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,8 +16,9 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # + Name: tcping -Version: 1.12.1 +Version: 1.19.1 Release: 0 Summary: A ping program for TCP ports License: MIT ++++++ tcping-1.12.1.tar.gz -> tcping-1.19.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/.github/ISSUE_TEMPLATE/bug_report.md new/tcping-1.19.1/.github/ISSUE_TEMPLATE/bug_report.md --- old/tcping-1.12.1/.github/ISSUE_TEMPLATE/bug_report.md 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/.github/ISSUE_TEMPLATE/bug_report.md 2023-03-04 17:28:54.000000000 +0100 @@ -1,10 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- **Describe the bug** @@ -12,6 +11,7 @@ **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +24,17 @@ If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new/tcping-1.19.1/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md --- old/tcping-1.12.1/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,17 +0,0 @@ -## Describe your changes - -## Issue ticket number and link - -## Checklist before requesting a review -- [ ] I have performed a self-review of my code -- [ ] If it is a core feature, I have added thorough tests. -- [ ] I have run `make check` and there are no failures. - -## Type of change - -Please delete options that are not relevant. - -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] This change requires a documentation update diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/.github/pull_request_template.md new/tcping-1.19.1/.github/pull_request_template.md --- old/tcping-1.12.1/.github/pull_request_template.md 1970-01-01 01:00:00.000000000 +0100 +++ new/tcping-1.19.1/.github/pull_request_template.md 2023-03-04 17:28:54.000000000 +0100 @@ -0,0 +1,26 @@ +# Important + +**Please provide the requested parameters below to help us review your pull request.** + +**Pull requests without a body or explanation will be rejected.** + +## Describe your changes + +## Issue ticket number and link + +Closes # + +## Checklist before requesting a review + +- [ ] I have performed a self-review of my code +- [ ] If it is a core feature, I have added tests. +- [ ] I have run `make check` and there are no failures. + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/.github/workflows/codeql-analysis.yml new/tcping-1.19.1/.github/workflows/codeql-analysis.yml --- old/tcping-1.12.1/.github/workflows/codeql-analysis.yml 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/.github/workflows/codeql-analysis.yml 2023-03-04 17:28:54.000000000 +0100 @@ -40,6 +40,12 @@ - name: Checkout repository uses: actions/checkout@v3 + - name: Setting Go version + uses: actions/setup-go@v3.3.1 + with: + go-version-file: "go.mod" + check-latest: true + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/.github/workflows/container-publish.yml new/tcping-1.19.1/.github/workflows/container-publish.yml --- old/tcping-1.12.1/.github/workflows/container-publish.yml 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/.github/workflows/container-publish.yml 2023-03-04 17:28:54.000000000 +0100 @@ -34,6 +34,18 @@ id-token: write steps: + - name: Extract Version + id: version_step + run: | + echo "##[set-output name=version;]VERSION=${GITHUB_REF#$"refs/tags/v"}" + echo "##[set-output name=version_tag;]$GITHUB_REPOSITORY:${GITHUB_REF#$"refs/tags/v"}" + echo "##[set-output name=latest_tag;]$GITHUB_REPOSITORY:latest" + - name: Print Version + run: | + echo ${{steps.version_step.outputs.version}} + echo ${{steps.version_step.outputs.version_tag}} + echo ${{steps.version_step.outputs.latest_tag}} + - name: Checkout repository uses: actions/checkout@v3 @@ -41,16 +53,23 @@ # https://github.com/sigstore/cosign-installer - name: Install cosign if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@441a29ec473755b0bc3a2be555989a1f8cef321d + uses: sigstore/cosign-installer@7bca8b41164994a7dc93749d266e2f1db492f8a2 with: - cosign-release: "v1.9.0" + cosign-release: "v1.13.1" # Workaround: https://github.com/docker/build-push-action/issues/461 - name: Setup Docker buildx uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf + - name: Setting Go version + uses: actions/setup-go@v3.3.1 + with: + go-version-file: "go.mod" + check-latest: true + # cache: true + - name: Log in to Docker Hub - uses: docker/login-action@d398f07826957cd0a18ea1b059cf1207835e60bc + uses: docker/login-action@v2.1.0 with: username: ${{ secrets.DOCKER_HUB_USER }} password: ${{ secrets.DOCKER_HUB_PASS }} @@ -59,18 +78,12 @@ # https://github.com/docker/login-action - name: Log into registry ${{ env.REGISTRY }} if: github.event_name != 'pull_request' - uses: docker/login-action@d398f07826957cd0a18ea1b059cf1207835e60bc + uses: docker/login-action@v2.1.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Setting Go version - uses: actions/setup-go@v3.2.0 - with: - go-version-file: "go.mod" - # go-version: "^1.18.1" - - name: build Docker image using Makefile run: make gitHubActions @@ -78,18 +91,17 @@ # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@97c170d70b5f8bfc77e6b23e68381f217cb64ded + uses: docker/metadata-action@v4.1.1 with: - # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: | pouriyajamshidi/tcping ghcr.io/${{ github.repository }} tags: | - type=ref,event=tag + type=semver,pattern={{version}} type=raw,value=latest,enable={{is_default_branch}} + # type=ref,event=tag # type=ref,event=pr # type=semver,pattern={{raw}} - # type=semver,pattern={{version}} # type=semver,pattern={{major}}.{{minor}} # type=semver,pattern={{major}} @@ -98,7 +110,6 @@ - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@42863b1282f7046f6c1ec9222965bbceafae3bb8 - # actions/setup-go@v3.2.0 with: context: . push: ${{ github.event_name != 'pull_request' }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/.github/workflows/stale.yml new/tcping-1.19.1/.github/workflows/stale.yml --- old/tcping-1.12.1/.github/workflows/stale.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/tcping-1.19.1/.github/workflows/stale.yml 2023-03-04 17:28:54.000000000 +0100 @@ -0,0 +1,28 @@ +name: "Close stale issues and PRs" +on: + schedule: + - cron: "30 23 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: read + pull-requests: write + steps: + - uses: actions/stale@v6.0.1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + exempt-assignees: "pouriyajamshidi" + exempt-pr-labels: "security" + exempt-issue-labels: "security" + stale-pr-message: | + This pull request has been automatically marked as stale because it has not had recent activity. + It will be closed in 7 days if no further activity occurs. + Let's figure out how to push this issue forward together by commenting here. + + Thank you for your contribution! + close-pr-message: | + This pull request has been automatically closed because it has not had recent activity or follow ups. + days-before-stale: 30 + days-before-close: 7 Binary files old/tcping-1.12.1/Artwork/tcping_logo2.png and new/tcping-1.19.1/Artwork/tcping_logo2.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/CHANGELOG.md new/tcping-1.19.1/CHANGELOG.md --- old/tcping-1.12.1/CHANGELOG.md 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/CHANGELOG.md 2023-03-04 17:28:54.000000000 +0100 @@ -1,5 +1,34 @@ # Changelog +## v1.19.0 - 2023-2-26 + +- implmenet sub-millisecond timing report to make it suitable for Data center and Cloud environments +- refactor `tcping` function and simplify it +- fix downtime report miscalculation +- fix picking of go version +- improve build process +- changed `ipAddress` type from string to `netip.Addr` thanks @segfault99 +- fix `statsprinter` formats thanks @segfault99 +- upgrade actions thanks @wutingfeng +- fix undeclared `statsPrinter` warning +- fix code scanning alert - Incorrect conversion between integer types #43 +- add `stale` workflow +- add new logo +- add Linux brew section +- add docker demo recording +- restructure README file +- update dependencies and bump Go version +- improve Makefile +- fix tag detection on Actions workflow +- add `Go` version to `CodeQL` +- add `downloads` badge +- improve checkUpdate message +- fix go install guide +- fix bug report template +- create SECURITY.md +- improve pull request template +- improve stale workflow + ## v1.12.0 - 2022-7-10 - add preliminary JSON output support thanks @icemint0828 for collaboration diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/Makefile new/tcping-1.19.1/Makefile --- old/tcping-1.12.1/Makefile 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/Makefile 2023-03-04 17:28:54.000000000 +0100 @@ -1,11 +1,11 @@ EXEC_DIR = executables/ SOURCE_FILES = $(tcping.go statsprinter.go) -.PHONY: all build clean format test vet gitHubActions container +.PHONY: all build update clean format test vet gitHubActions container all: build check: format vet test -build: clean format vet test +build: clean update format vet test @mkdir -p $(EXEC_DIR) @@ -13,7 +13,7 @@ @go build -ldflags "-s -w" -o $(EXEC_DIR)tcping $(SOURCE_FILES) @echo "[+] Packaging the Linux version" - @zip -j $(EXEC_DIR)tcping_Linux.zip $(EXEC_DIR)tcping > /dev/null + @tar -czvf $(EXEC_DIR)tcping_Linux.tar.gz -C $(EXEC_DIR) tcping > /dev/null @echo "[+] Removing the Linux binary" @rm $(EXEC_DIR)tcping @@ -33,18 +33,32 @@ @env GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o $(EXEC_DIR)tcping $(SOURCE_FILES) @echo "[+] Packaging the MacOS version" - @zip -j $(EXEC_DIR)tcping_MacOS.zip $(EXEC_DIR)tcping > /dev/null + @tar -czvf $(EXEC_DIR)tcping_MacOS.tar.gz -C $(EXEC_DIR) tcping > /dev/null @echo "[+] Removing the MacOS binary" @rm $(EXEC_DIR)tcping + @echo + @echo "[+] Building the MacOS ARM version" + @env GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w" -o $(EXEC_DIR)tcping $(SOURCE_FILES) + + @echo "[+] Packaging the MacOS ARM version" + @tar -czvf $(EXEC_DIR)tcping_MacOS_ARM.tar.gz -C $(EXEC_DIR) tcping > /dev/null + + @echo "[+] Removing the MacOS ARM binary" + @rm $(EXEC_DIR)tcping + + @echo "[+] Done" + +update: + @echo "[+] Updating Go dependencies" + @go get -u @echo "[+] Done" clean: @echo "[+] Cleaning files" @rm -rf $(EXEC_DIR) @echo "[+] Done" - @echo format: @echo "[+] Formatting files" @@ -58,6 +72,12 @@ @echo "[+] Running tests" @go test +tidyup: + @echo "[+] Tidying up" + @go get -u + @go get -u ./... + @go mod tidy + container: @echo "[+] Building container image" @env GOOS=linux CGO_ENABLED=0 go build --ldflags '-s -w -extldflags "-static"' -o $(EXEC_DIR)tcpingDocker $(SOURCE_FILES) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/README.md new/tcping-1.19.1/README.md --- old/tcping-1.12.1/README.md 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/README.md 2023-03-04 17:28:54.000000000 +0100 @@ -1,5 +1,5 @@ <div align="center" style="width: 100%;"> - <img alt="tcping" src="Artwork/tcping_logo.png" style="width:50%;"> + <img alt="tcping" src="Artwork/tcping_logo2.png" style="width:50%;"> </div> # TCPING @@ -10,17 +10,19 @@ [](https://github.com/pouriyajamshidi/tcping/actions/workflows/container-publish.yml)  [](https://badge.fury.io/go/github.com%2Fpouriyajamshidi%2Ftcping) + + A cross-platform ping program for `TCP` ports inspired by the Linux's ping utility. This program will send `TCP` probes to an `IP address` or a `hostname` specified by you and prints the result. It works with both `IPv4` and `IPv6`. TCPING uses different `TCP sequence numbering` for successful and unsuccessful probes, so that when you look at the results and spot a failed probe, understanding the total packet drops to that point would be illustrative enough. - Monitor your network connection. -- Calculate packet loss. -- Assess the latency of your network. +- Determine packet loss. +- Analyze the network's latency. - Show `min`/`avg`/`max` probes latency. -- Retry resolving a hostname after a certain number of ping failures by using the `-r` flag. This option is useful if you are testing your Global Server Load Balancer (GSLB) or DNS load balancing. -- Print connection statistics on `Enter` key press. +- Print connection statistics by pressing the `Enter` key and without stopping the program. +- Use the `-r` flag to retry hostname resolution after a predetermined number of ping failures. If you want to test your `DNS` load balancing or Global Server Load Balancer `(GSLB)`, you should utilize this option.. - Display the longest encountered downtime and uptime duration and time. - Monitor and audit your peers network. - Calculate the total uptime/downtime when conducting a maintenance. @@ -35,7 +37,7 @@ - [Demos](#demos) - [Vanilla usage](#vanilla-usage) - [Retry resolve (`-r`) flag](#retry-resolve--r-flag) - - [Download the executables for](#download-the-executables-for) + - [Download](#download) - [Usage](#usage) - [On `Linux` and `macOS`](#on-linux-and-macos) - [On `Windows`](#on-windows) @@ -45,7 +47,7 @@ - [Notes](#notes) - [Contributing](#contributing) - [Tested on](#tested-on) - - [Sponsor us](#sponsor-us) + - [Sponsor The Project](#sponsor-the-project) - [Contact me](#contact-me) - [License](#license) @@ -65,28 +67,20 @@ --- -## Download the executables for +## Download - ### [Windows](https://github.com/pouriyajamshidi/tcping/releases/latest/download/tcping_Windows.zip) -- ### [Linux](https://github.com/pouriyajamshidi/tcping/releases/latest/download/tcping_Linux.zip) +- ### [Linux](https://github.com/pouriyajamshidi/tcping/releases/latest/download/tcping_Linux.tar.gz) - Also available through `brew` -- ### [macOS](https://github.com/pouriyajamshidi/tcping/releases/latest/download/tcping_MacOS.zip) - also available through `brew` +- ### [macOS](https://github.com/pouriyajamshidi/tcping/releases/latest/download/tcping_MacOS.tar.gz) - Also available through `brew` - ```bash - brew install pouriyajamshidi/tap/tcping - ``` +- ### [macOS M1 - ARM](https://github.com/pouriyajamshidi/tcping/releases/latest/download/tcping_MacOS_ARM.tar.gz) - Also available through `brew` When the download is complete, head to the [usage](#usage) section. **Alternatively**, you can: -- Install using `go get`: - - ```bash - go get github.com/pouriyajamshidi/tcping - ``` - - Use the `Docker` images: ```bash @@ -99,6 +93,18 @@ docker pull ghcr.io/pouriyajamshidi/tcping:latest ``` +- Install using `go install`: + + ```bash + go install github.com/pouriyajamshidi/tcping@latest + ``` + +- Install using `brew`: + + ```bash + brew install pouriyajamshidi/tap/tcping + ``` + - Or compile the code yourself by running the `make` command in the `tcping` directory: ```bash @@ -111,7 +117,7 @@ ## Usage -If you have decided to download the executables using the [aforementioned links](#download-the-executables-for) , go to the folder containing the file and extract it. Then, depending on your operating system, follow the instructions below: +If you have decided to download the executables using the [aforementioned links](#download-the-executables), go to the folder containing the file and extract it. Then, depending on your operating system, follow the instructions below: - [Linux and macOS](#on-linux-and-macos) - [Windows](#on-windows) @@ -119,25 +125,37 @@ ### On `Linux` and `macOS` +De-compress the downloaded file: + +```bash +tar -xvf tcping_Linux.tar.gz +# +# Or on Mac OS +# +tar -xvf tcping_MacOS.tar.gz +# +# on Mac OS ARM +# +tar -xvf tcping_MacOS_ARM.tar.gz +``` + Make the file executable: ```bash chmod +x tcping ``` -For easier use, copy the executable to your system `PATH` like `/usr/bin/`: +For easier use, copy the executable to your system `PATH` like `/usr/local/bin/`: ```bash -cp tcping /usr/bin/ +sudo cp tcping /usr/local/bin/ ``` Then run it like, `tcping <hostname/IP address> <port>`. For instance: ```bash tcping www.example.com 443 - # OR - tcping 10.10.10.1 22 ``` @@ -153,7 +171,7 @@ ### On `Windows` -I recommend [Windows Terminal](apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701) for the best experience and proper colorization. +We recommend [Windows Terminal](apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701) for the best experience and proper colorization. For easier use, copy `tcping.exe` to your system [PATH](https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/) like `C:\Windows\System32` and run it like: @@ -202,17 +220,23 @@ ## Tips -- While the program is running, press the `Enter` key to view the summary of all probes without exiting the program as depicted in the [demos](#Demos) section. +- Press the `Enter` key while the program is running to examine the summary of all probes without shutting it down, as shown in the [demos](#demos) section. --- ## Notes -TCPING is being constantly worked on and receives many new features and fixes. Make sure to check for newer versions. +`TCPING` is constantly being improved, adding numerous new features and fixing bugs. Be sure to look for updated versions.. + +```bash +tcping -u +``` ## Contributing -Pull requests are welcome to solve bugs, add new features and also to help me with the open issues that can be found here . +Pull requests are welcome to solve bugs, add new features and also to help me with the open issues that can be found [here](https://github.com/pouriyajamshidi/tcping/issues) + +Current number of open issues: . 1. Pick any issue that you feel comfortable with. 2. Fork the repository. @@ -222,13 +246,13 @@ 6. Run the tests `go test` or `make test`. 7. Create a pull request -Please make sure to only work on a specific issue on your pull request and not address two or more tickets in one PR. This will help me to review your pull request easier and also contributes to a cleaner git history. +Please make sure that your pull request only works on one specific issue and doesn't handle two or more tickets. This makes it simpler for us to examine your pull request and helps keep the git history clean. ## Tested on Windows, Linux and macOS. -## Sponsor us +## Sponsor The Project [](https://www.buymeacoffee.com/pouriyajamshidi) [](https://github.com/sponsors/pouriyajamshidi) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/SECURITY.md new/tcping-1.19.1/SECURITY.md --- old/tcping-1.12.1/SECURITY.md 1970-01-01 01:00:00.000000000 +0100 +++ new/tcping-1.19.1/SECURITY.md 2023-03-04 17:28:54.000000000 +0100 @@ -0,0 +1,15 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 1.x.x | :white_check_mark: | + + +## Reporting a Vulnerability + +Please report any security vulnerabilities by opening an issue [here](https://github.com/pouriyajamshidi/tcping/issues). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/go.mod new/tcping-1.19.1/go.mod --- old/tcping-1.12.1/go.mod 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/go.mod 2023-03-04 17:28:54.000000000 +0100 @@ -1,19 +1,19 @@ module github.com/pouriyajamshidi/tcping -go 1.18 +go 1.20 require ( - github.com/google/go-github/v45 v45.1.0 - github.com/gookit/color v1.5.1 - github.com/stretchr/testify v1.7.2 + github.com/google/go-github/v45 v45.2.0 + github.com/gookit/color v1.5.2 + github.com/stretchr/testify v1.8.0 ) require ( - github.com/davecgh/go-spew v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/crypto v0.6.0 // indirect + golang.org/x/sys v0.5.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/go.sum new/tcping-1.19.1/go.sum --- old/tcping-1.12.1/go.sum 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/go.sum 2023-03-04 17:28:54.000000000 +0100 @@ -1,27 +1,33 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-github/v45 v45.1.0 h1:SbUjHMRiCe9cHfu6Me4idWxLQEV8ZW9DLPz69zopyWo= -github.com/google/go-github/v45 v45.1.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= +github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI= +github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ= -github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= +github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= +github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 h1:z8Hj/bl9cOV2grsOpEaQFUaly0JWN3i97mo3jXKJNp0= -golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/statsprinter.go new/tcping-1.19.1/statsprinter.go --- old/tcping-1.12.1/statsprinter.go 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/statsprinter.go 2023-03-04 17:28:54.000000000 +0100 @@ -47,7 +47,7 @@ /* Print host name and port to use on tcping */ func (p *statsPlanePrinter) printStart() { - colorLightCyan("TCPinging %s on port %s\n", p.hostname, p.port) + colorLightCyan("TCPinging %s on port %d\n", p.hostname, p.port) } /* Print the last successful and unsuccessful probes */ @@ -161,11 +161,11 @@ colorCyan("avg") colorYellow("/") colorRed("max: ") - colorGreen("%d", rttResults.min) + colorGreen("%.3f", rttResults.min) colorYellow("/") - colorCyan("%.2f", rttResults.average) + colorCyan("%.3f", rttResults.average) colorYellow("/") - colorRed("%d", rttResults.max) + colorRed("%.3f", rttResults.max) colorYellow(" ms\n") /* duration stats */ @@ -176,18 +176,18 @@ func (p *statsPlanePrinter) printReply(replyMsg replyMsg) { if p.isIP { if replyMsg.msg == noReply { - colorRed("%s from %s on port %s TCP_conn=%d\n", + colorRed("%s from %s on port %d TCP_conn=%d\n", replyMsg.msg, p.ip, p.port, p.totalUnsuccessfulPkts) } else { - colorLightGreen("%s from %s on port %s TCP_conn=%d time=%d ms\n", + colorLightGreen("%s from %s on port %d TCP_conn=%d time=%.3f ms\n", replyMsg.msg, p.ip, p.port, p.totalSuccessfulPkts, replyMsg.rtt) } } else { if replyMsg.msg == noReply { - colorRed("%s from %s (%s) on port %s TCP_conn=%d\n", + colorRed("%s from %s (%s) on port %d TCP_conn=%d\n", replyMsg.msg, p.hostname, p.ip, p.port, p.totalUnsuccessfulPkts) } else { - colorLightGreen("%s from %s (%s) on port %s TCP_conn=%d time=%d ms\n", + colorLightGreen("%s from %s (%s) on port %d TCP_conn=%d time=%.3f ms\n", replyMsg.msg, p.hostname, p.ip, p.port, p.totalSuccessfulPkts, replyMsg.rtt) } } @@ -195,7 +195,7 @@ /* Print the total downtime */ func (p *statsPlanePrinter) printTotalDownTime(now time.Time) { - latestDowntimeDuration := p.startOfDowntime.Sub(now).Seconds() + latestDowntimeDuration := time.Since(p.startOfDowntime).Seconds() calculatedDowntime := calcTime(uint(math.Ceil(latestDowntimeDuration))) colorYellow("No response received for %s\n", calculatedDowntime) } @@ -208,7 +208,7 @@ uptime := calcTime(uint(math.Ceil(p.longestUptime.duration))) - colorYellow("longest consecutive uptime: ") + colorYellow("longest consecutive uptime: ") colorGreen("%v ", uptime) colorYellow("from ") colorLightBlue("%v ", p.longestUptime.start.Format(timeFormat)) @@ -263,7 +263,7 @@ /* Print host name and port to use on tcping in JSON format */ func (j *statsJsonPrinter) printStart() { - jsonPrintf("TCPinging %s on port %s", j.hostname, j.port) + jsonPrintf("TCPinging %s on port %d", j.hostname, j.port) } /* Print the last successful and unsuccessful probes in JSON format */ @@ -359,7 +359,7 @@ } /* latency stats.*/ - jsonPrintf("rtt min/avg/max: %d/%2f/%d", rttResults.min, rttResults.average, rttResults.max) + jsonPrintf("rtt min/avg/max: %.3f/%.3f/%.3f", rttResults.min, rttResults.average, rttResults.max) /* duration stats */ j.printDurationStats() @@ -369,18 +369,18 @@ func (j *statsJsonPrinter) printReply(replyMsg replyMsg) { if j.isIP { if replyMsg.msg == noReply { - jsonPrintf("%s from %s on port %s TCP_conn=%d", + jsonPrintf("%s from %s on port %d TCP_conn=%d", replyMsg.msg, j.ip, j.port, j.totalUnsuccessfulPkts) } else { - jsonPrintf("%s from %s on port %s TCP_conn=%d time=%d ms", + jsonPrintf("%s from %s on port %d TCP_conn=%d time=%.3f ms", replyMsg.msg, j.ip, j.port, j.totalSuccessfulPkts, replyMsg.rtt) } } else { if replyMsg.msg == noReply { - jsonPrintf("%s from %s (%s) on port %s TCP_conn=%d", + jsonPrintf("%s from %s (%s) on port %d TCP_conn=%d", replyMsg.msg, j.hostname, j.ip, j.port, j.totalUnsuccessfulPkts) } else { - jsonPrintf("%s from %s (%s) on port %s TCP_conn=%d time=%d ms", + jsonPrintf("%s from %s (%s) on port %d TCP_conn=%d time=%.3f ms", replyMsg.msg, j.hostname, j.ip, j.port, j.totalSuccessfulPkts, replyMsg.rtt) } } @@ -388,7 +388,7 @@ /* Print the total downtime in JSON format */ func (j *statsJsonPrinter) printTotalDownTime(now time.Time) { - latestDowntimeDuration := j.startOfDowntime.Sub(now).Seconds() + latestDowntimeDuration := time.Since(j.startOfDowntime).Seconds() calculatedDowntime := calcTime(uint(math.Ceil(latestDowntimeDuration))) jsonPrintf("No response received for %s", calculatedDowntime) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tcping-1.12.1/tcping.go new/tcping-1.19.1/tcping.go --- old/tcping-1.12.1/tcping.go 2022-07-10 21:19:18.000000000 +0200 +++ new/tcping-1.19.1/tcping.go 2023-03-04 17:28:54.000000000 +0100 @@ -6,6 +6,7 @@ "flag" "fmt" "net" + "net/netip" "os" "os/signal" "regexp" @@ -17,26 +18,26 @@ ) type stats struct { - startTime time.Time endTime time.Time startOfUptime time.Time startOfDowntime time.Time lastSuccessfulProbe time.Time lastUnsuccessfulProbe time.Time + ip ipAddress + startTime time.Time statsPrinter retryHostnameResolveAfter *uint // Retry resolving target's hostname after a certain number of failed requests - ip string - port string hostname string - rtt []uint - totalUnsuccessfulPkts uint + rtt []float32 + ongoingUnsuccessfulPkts uint longestDowntime longestTime totalSuccessfulPkts uint totalUptime time.Duration - ongoingUnsuccessfulPkts uint retriedHostnameResolves uint longestUptime longestTime totalDowntime time.Duration + totalUnsuccessfulPkts uint + port uint16 wasDown bool // Used to determine the duration of a downtime isIP bool // If IP is provided instead of hostname, suppresses printing the IP information twice shouldRetryResolve bool @@ -49,23 +50,23 @@ } type rttResults struct { - min uint - max uint + min float32 + max float32 average float32 hasResults bool } type replyMsg struct { msg string - rtt int64 + rtt float32 } -type ipAddress = string +type ipAddress = netip.Addr type cliArgs = []string type calculatedTimeString = string const ( - version = "1.12.0" + version = "1.19.0" owner = "pouriyajamshidi" repo = "tcping" thousandMilliSecond = 1000 * time.Millisecond @@ -141,18 +142,24 @@ } /* the non-flag command-line arguments */ - port, _ := strconv.Atoi(args[1]) + port, err := strconv.ParseUint(args[1], 10, 16) + + if err != nil { + colorRed("Invalid port number: %s\n", args[1]) + os.Exit(1) + } + if port < 1 || port > 65535 { print("Port should be in 1..65535 range\n") os.Exit(1) } tcpStats.hostname = args[0] - tcpStats.port = strconv.Itoa(port) + tcpStats.port = uint16(port) tcpStats.ip = resolveHostname(tcpStats) tcpStats.startTime = getSystemTime() - if tcpStats.hostname == tcpStats.ip { + if tcpStats.hostname == tcpStats.ip.String() { tcpStats.isIP = true } @@ -168,7 +175,9 @@ } } -/* Permute args for flag parsing stops just before the first non-flag argument. +/* + Permute args for flag parsing stops just before the first non-flag argument. + see: https://pkg.go.dev/flag */ func permuteArgs(args cliArgs) { @@ -232,17 +241,16 @@ colorLightBlue("Please update TCPING from the URL below:\n") colorLightBlue("https://github.com/%s/%s/releases/tag/%s\n", owner, repo, latestTagName) } else { - colorLightBlue("Newer version not found . Your version %s is the latest.\n", version) + colorLightBlue("Newer version not found. %s is the latest version.\n", version) } os.Exit(0) } /* Hostname resolution */ func resolveHostname(tcpStats *stats) ipAddress { - ipRaw := net.ParseIP(tcpStats.hostname) - - if ipRaw != nil { - return ipRaw.String() + ip, err := netip.ParseAddr(tcpStats.hostname) + if err == nil { + return ip } ipAddr, err := net.LookupIP(tcpStats.hostname) @@ -255,7 +263,8 @@ os.Exit(1) } - return ipAddr[0].String() + ip, _ = netip.ParseAddr(ipAddr[0].String()) + return ip } /* Retry resolve hostname after certain number of failures */ @@ -278,12 +287,15 @@ } /* Find min/avg/max RTT values. The last int acts as err code */ -func findMinAvgMaxRttTime(timeArr []uint) rttResults { - arrLen := len(timeArr) - var accum uint - +func findMinAvgMaxRttTime(timeArr []float32) rttResults { + var accum float32 var rttResults rttResults - rttResults.min = ^uint(0) + + arrLen := len(timeArr) + // rttResults.min = ^uint(0.0) + if arrLen > 0 { + rttResults.min = timeArr[0] + } for i := 0; i < arrLen; i++ { accum += timeArr[i] @@ -299,7 +311,7 @@ if arrLen > 0 { rttResults.hasResults = true - rttResults.average = float32(accum) / float32(arrLen) + rttResults.average = accum / float32(arrLen) } return rttResults @@ -385,72 +397,64 @@ return time.Now() } -/* Ping host, TCP style */ -func tcping(tcpStats *stats) { - - IPAndPort := net.JoinHostPort(tcpStats.ip, tcpStats.port) +func nanoToMillisecond(nano int64) float32 { + return float32(nano) / 1e6 +} - connStart := getSystemTime() - conn, err := net.DialTimeout("tcp", IPAndPort, oneSecond) - connEnd := time.Since(connStart) +func (tcpStats *stats) handleConnError(now time.Time) { + if !tcpStats.wasDown { + tcpStats.startOfDowntime = now + calcLongestUptime(tcpStats, now) + tcpStats.startOfUptime = time.Time{} + tcpStats.wasDown = true + } - rtt := connEnd.Milliseconds() - now := getSystemTime() + tcpStats.totalDowntime += time.Second + tcpStats.totalUnsuccessfulPkts += 1 + tcpStats.lastUnsuccessfulProbe = now + tcpStats.ongoingUnsuccessfulPkts += 1 - if err != nil { - /* if the previous probe was successful - and the current one failed: */ - if !tcpStats.wasDown { - /* Update startOfDowntime */ - tcpStats.startOfDowntime = now - - /* Calculate the longest uptime */ - endOfUptime := now - calcLongestUptime(tcpStats, endOfUptime) - tcpStats.startOfUptime = time.Time{} + tcpStats.statsPrinter.printReply(replyMsg{msg: "No reply", rtt: 0}) +} - tcpStats.wasDown = true - } +func (tcpStats *stats) handleConnSuccess(rtt float32, now time.Time) { + if tcpStats.wasDown { + tcpStats.statsPrinter.printTotalDownTime(now) + tcpStats.startOfUptime = now + calcLongestDowntime(tcpStats, now) + tcpStats.startOfDowntime = time.Time{} + tcpStats.wasDown = false + tcpStats.ongoingUnsuccessfulPkts = 0 + } - tcpStats.totalDowntime += time.Second - tcpStats.totalUnsuccessfulPkts += 1 - tcpStats.lastUnsuccessfulProbe = now - tcpStats.ongoingUnsuccessfulPkts += 1 + if tcpStats.startOfUptime.Format(timeFormat) == nullTimeFormat { + tcpStats.startOfUptime = now + } - tcpStats.printReply(replyMsg{msg: "No reply", rtt: 0}) - } else { - /* if the previous probe failed - and the current one succeeded: */ - if tcpStats.wasDown { - /* calculate the total downtime since - the previous successful probe */ - tcpStats.printTotalDownTime(now) - - /* Update startOfUptime */ - tcpStats.startOfUptime = now - - /* Calculate the longest downtime */ - endOfDowntime := now - calcLongestDowntime(tcpStats, endOfDowntime) - tcpStats.startOfDowntime = time.Time{} + tcpStats.totalUptime += time.Second + tcpStats.totalSuccessfulPkts += 1 + tcpStats.lastSuccessfulProbe = now + tcpStats.rtt = append(tcpStats.rtt, rtt) - tcpStats.wasDown = false - tcpStats.ongoingUnsuccessfulPkts = 0 - } + tcpStats.statsPrinter.printReply(replyMsg{msg: "Reply", rtt: rtt}) +} - /* It means it is the first time to get a response*/ - if tcpStats.startOfUptime.Format(timeFormat) == nullTimeFormat { - tcpStats.startOfUptime = now - } +/* Ping host, TCP style */ +func tcping(tcpStats *stats) { + IPAndPort := netip.AddrPortFrom(tcpStats.ip, tcpStats.port) - tcpStats.totalUptime += time.Second - tcpStats.totalSuccessfulPkts += 1 - tcpStats.lastSuccessfulProbe = now + connStart := getSystemTime() + conn, err := net.DialTimeout("tcp", IPAndPort.String(), oneSecond) + connEnd := time.Since(connStart) - tcpStats.rtt = append(tcpStats.rtt, uint(rtt)) - tcpStats.printReply(replyMsg{msg: "Reply", rtt: rtt}) + rtt := nanoToMillisecond(connEnd.Nanoseconds()) + now := getSystemTime() - defer conn.Close() + if err != nil { + tcpStats.handleConnError(now) + } else { + tcpStats.handleConnSuccess(rtt, now) + conn.Close() } time.Sleep(thousandMilliSecond - connEnd) ++++++ vendor.tar.gz ++++++ ++++ 6700 lines of diff (skipped)