diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..f899017 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,29 @@ +name: Continuous Integration + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + name: Build and Test + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.21.5 + + - name: Build + run: go build -v ./... + + - name: Run tests + run: go test -v ./... diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..49c0d6b --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,29 @@ +name: Release + +on: + push: + tags: + - '*' + workflow_dispatch: + inputs: + version: + description: 'Version (e.g., 1.0.0)' + required: true + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.21.5 + + - name: Run GoReleaser + if: github.event_name == 'workflow_dispatch' + run: goreleaser release --rm-dist --release-notes "Release version ${{ github.event.inputs.version }}" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 3b735ec..d8a65c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,11 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib +ipt +dist/ # Test binary, built with `go test -c` *.test @@ -19,3 +18,24 @@ # Go workspace file go.work + +# Ignore JetBrains IntelliJ IDEA project files +.idea/ + +# Ignore Visual Studio Code project files +.vscode/ + +# Ignore temporary directories and files +.idea/ +.vscode/ +.idea_modules/ +.idea_caches/ +out/ +.idea.vim/ +.idea_workspace/ + +# Ignore project files generated by IntelliJ IDEA +*.iml +*.ipr +*.iws +*.idea_modules \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..e1aa07d --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,54 @@ +# .goreleaser.yml +# This is the GoReleaser configuration file which defines how to build, package, and release your application. + +project_name: ipt # The name of your project. + +# Build section defines how your application should be built. +builds: + - id: ipt + main: . # Path to the main source file or directory of your program. + binary: ipt # Name of the compiled binary. + goos: # List of target operating systems. + - linux + - darwin + goarch: # List of target architectures. + - amd64 + - arm64 + env: # Environment variables to be set during the build process. + - CGO_ENABLED=0 + ldflags: # Flags to pass to the go compiler. + - -s -w + +# Archives section defines how to package your binary. +archives: + - id: archive + builds: + - ipt + format: tar.gz # Format for Linux binaries. + format_overrides: + - goos: darwin + format: zip # Format for macOS binaries. + wrap_in_directory: true + files: # Additional files to include in the archive. + - LICENSE + - README.md + +# Release section configures how to handle GitHub releases. +release: + github: + owner: debek + name: ipt + draft: true # Indicates whether the release should be a draft. + prerelease: auto # Automatically set whether the release is a prerelease based on the tag. + +# Checksum section generates checksums of your binaries. +checksum: + name_template: 'checksums.txt' + +# Snapshot section configures the creation of snapshots. +snapshot: + name_template: "{{ .Tag }}-next" # Template for naming snapshot releases. + +# Changelog section configures how the changelog should be handled. +changelog: + skip: false # Indicates whether to skip generating the changelog. diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md new file mode 100644 index 0000000..2b93a3c --- /dev/null +++ b/CONTRIBUTE.md @@ -0,0 +1,32 @@ +# Contributing to IPT + +Thank you for your interest in contributing to ipt! All contributions, whether code, bug reports, or feature suggestions, are greatly appreciated. + +## How Can I Contribute? + +### Reporting Bugs and Suggesting Features +- If you encounter a bug or have an idea for a new feature, please create an issue in our GitHub repository. +- Describe the bug or feature as detailed as possible to help us understand your intentions. + +### Creating Pull Requests +- Fork the repository. +- Create a new branch for your changes (`git checkout -b my-new-feature`). +- Make your changes in the code. +- Ensure code is well-formatted and follows the project's coding standards. +- Commit your changes (`git commit -am 'Add some feature'`). +- Push to your fork (`git push origin my-new-feature`). +- Submit a Pull Request to our repository. + +### Guidelines +- Make sure your changes are well documented. +- Add tests for new features. +- Follow the established coding standards. + +## Coding and Testing +- We encourage clear and understandable coding. +- Unit tests are an essential part of development. Try to maintain high test coverage. + +## Questions? +If you have any questions or concerns, don't hesitate to ask. We are here to help! + +Thank you for your contributions to the ipt project! diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc116be --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# IPT (IP Test) - Connection Tester + +IPT (IP Tester) is a Go language application designed to test TCP connections to specified IP addresses and ports. It provides easy-to-interpret, color-coded output to quickly distinguish between successful and failed connections. + +## Features + +- TCP connection testing to a specified IP address and port. +- Customizable connection timeout setting. +- Color-coded output for clear distinction of success (green) and failure (red). + +## Requirements + +- Go (Golang) version 1.x (if using `go install`). +- Or, directly use the provided binary for your platform. + +## Installation + +### Using Precompiled Binary (Recommended) + +1. Download the latest binary for your platform from the Releases page. +2. Place the binary in a directory included in your system's PATH (e.g., `/usr/local/bin` on macOS/Linux). + +### Using `go install` (For Go Developers) + +If you have Go installed and prefer to build from source: + +`go install github.com//ipt@latest` + +This will install the `ipt` binary in your `$GOPATH/bin` directory. + +## Usage + +Run the program with the following arguments: + +`ipt []` + +- `ip_address`: The IP address of the server you want to connect to. +- `port`: The server's port. +- `timeout`: Optional connection timeout (default is 5 seconds). Specify the time in a format like '5s' for 5 seconds. + +## Examples + +- Testing connection to a server on port 80: +- `ipt 192.168.1.1 80` + +- Testing connection to a server on port 443 with a 10-second timeout: +- `ipt 192.168.1.1 443 10s` + +## Contributing + +Contributions to this project are welcome! Please see the [CONTRIBUTE.md](https://chat.openai.com/g/CONTRIBUTE.md) file for guidelines on how to contribute. + +## License + +This project is licensed under the MIT License. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1bb8d14 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/debek/ipt + +go 1.21.5 diff --git a/main.go b/main.go new file mode 100644 index 0000000..c70e12b --- /dev/null +++ b/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "net" + "os" + "time" +) + +const ( + Red = "\033[31m" + Green = "\033[32m" + Reset = "\033[0m" +) + +func main() { + if len(os.Args) < 3 { + fmt.Println("Usage: ipt []") + os.Exit(1) + } + + ip := os.Args[1] + port := os.Args[2] + timeout := "5s" + + if len(os.Args) == 4 { + timeout = os.Args[3] + "s" + } + + timeoutDuration, err := time.ParseDuration(timeout) + if err != nil { + fmt.Printf(Red+"Error: Invalid timeout format: '%s'. Please provide time in format like '5s' for 5 seconds.\n"+Reset, timeout) + os.Exit(1) + } + + startTime := time.Now() + fmt.Printf("[%s] START: Connection Test to %s:%s with a timeout of %s.\n", startTime.Format("2006-01-02 15:04:05"), ip, port, timeoutDuration) + + for { + currentTime := time.Now() + err := checkConnection(ip, port, timeoutDuration) + if err != nil { + if netErr, ok := err.(net.Error); ok && netErr.Timeout() { + fmt.Printf(Red+"[%s] FAILURE: Connection to %s:%s timed out (possible firewall rejection)\n"+Reset, currentTime.Format("2006-01-02 15:04:05"), ip, port) + } else { + fmt.Printf(Red+"[%s] FAILURE: Connection to %s:%s failed (service not running or blocked)\n"+Reset, currentTime.Format("2006-01-02 15:04:05"), ip, port) + } + } else { + fmt.Printf(Green+"[%s] SUCCESS: Connected to %s:%s\n"+Reset, currentTime.Format("2006-01-02 15:04:05"), ip, port) + } + time.Sleep(1 * time.Second) + } +} + +func checkConnection(ip string, port string, timeout time.Duration) error { + address := net.JoinHostPort(ip, port) + conn, err := net.DialTimeout("tcp", address, timeout) + if err != nil { + return err + } + defer conn.Close() + return nil +}