# Understanding the croc.go Main Client Implementation in Croc

> Discover the croc.go main client implementation in schollz/croc. Learn how it orchestrates file transfers, from discovery to secure data streaming and reconnections.

- Repository: [Zack/croc](https://github.com/schollz/croc)
- Tags: internals
- Published: 2026-07-26

---

**The [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) main client implementation serves as the central orchestrator for the croc file-transfer tool, managing the complete lifecycle from CLI option parsing and peer discovery to PAKE-based key exchange, secure data streaming, and fault-tolerant reconnections.**

The [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) file in the `schollz/croc` repository contains the core client logic that transforms command-line flags into secure peer-to-peer file transfers. This single file coordinates cryptography, network resilience, and user interaction to provide a seamless transfer experience without requiring server infrastructure or port forwarding.

## Configuration and Options Management

At the heart of the client lies the **`Options`** struct, defined at lines 73-103, which aggregates every CLI flag required for operation. This structure captures critical parameters including **`IsSender`** to distinguish transfer direction, **`RelayAddress`** for custom relay endpoints, **`SharedSecret`** for authentication, and **`ThrottleUpload`** for bandwidth management. By centralizing configuration in this struct, [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) ensures type-safe access to user preferences throughout the transfer lifecycle.

## Client Initialization and Security Setup

The **`New`** function (lines 28-86) constructs a **`Client`** object and prepares the cryptographic environment for secure communication. For receivers, it initializes the **PAKE (Password-Authenticated Key Exchange)** instance using the shared secret, while all clients derive a room name by hashing that secret to identify the relay channel. The function also configures rate limiters when throttling is enabled, establishing the foundation for the secure channel setup.

## File Discovery and Metadata Handling

Before transmission begins, **`GetFilesInfo`** and its companion **`GetFilesInfoWithExactExclusions`** (lines 63-71) recursively traverse the supplied file paths to build comprehensive **`FileInfo`** structures. These functions respect **`.gitignore`** patterns when requested, compute cryptographic hashes for integrity verification, and catalog metadata including file sizes and folder structures. This discovery phase ensures the receiver obtains an accurate manifest before accepting data.

## Local Relay and Peer Discovery

When public relay connectivity is unavailable or undesirable, [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) implements LAN-only fallback mechanisms through several specialized methods. **`setupLocalRelay`** initializes an ephemeral relay instance on the local machine, while **`broadcastOnLocalNetwork`** and **`discoverReceivePeers`** (lines 29-33, 84-92) handle UDP broadcasting and peer discovery within the local subnet. These capabilities enable direct machine-to-machine transfers without internet connectivity.

## PAKE Handshake and Channel Security

The transfer process relies on **`senderWaitForHandshake`** and the early stages of **`transfer`** (lines 143-151, 98-104) to execute the PAKE protocol, exchanging `pake1` and `pake2` messages to derive symmetric session keys. Once keys are established, the client marks **`Step1ChannelSecured`** (lines 98-108) and transitions to encrypted communication using **AES-GCM** as implemented in the `crypt` package. This handshake ensures that only parties possessing the shared secret can decrypt the subsequent data stream.

## Data Transfer and Flow Control

Actual file transmission occurs through **`sendCollectFiles`** and the main **`transfer`** method (lines 71-80, 86-94), which handle chunking, hashing, and progress tracking. The client streams file chunks while respecting the configured rate limiter to prevent network saturation, updating progress indicators in real-time. For integrity verification, each chunk's hash is validated against the metadata collected during the discovery phase.

## Reconnection and Fault Tolerance

Network disruptions are managed through **`transferWithReconnect`**, **`canRetryTransfer`**, and **`reconnectRelayAttempt`** (lines 56-65, 70-78), which implement bounded retry logic with exponential backoff. If the primary relay connection fails, the client can automatically reconnect to the relay or fall back to alternate sender routes without user intervention. This resilience ensures transfers complete successfully despite transient connectivity issues.

## User Feedback and Interface

Upon initiating a transfer, the **`Send`** method (lines 138-150) generates the transfer code, optionally creates a **QR code** for mobile convenience, and copies the receive command to the system clipboard. These interface conveniences allow recipients to join transfers quickly using the shared secret. The client also outputs debug information and transfer statistics to keep users informed of progress and potential issues.

## Practical Implementation Examples

The following examples demonstrate how to programmatically interact with the [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) client implementation.

### Sending Files

```go
ops := croc.Options{
    IsSender:      true,
    SharedSecret:  "my-secret-code",
    RelayAddress:  "relay.croc.io:9009",
    Debug:         false,
}
client, err := croc.New(ops)
if err != nil {
    log.Fatalf("init error: %v", err)
}
files, empty, totalFolders, err := croc.GetFilesInfo([]string{"myfile.txt"}, false, false, nil)
if err != nil {
    log.Fatalf("file discovery error: %v", err)
}
if err := client.Send(files, empty, totalFolders); err != nil {
    log.Fatalf("transfer error: %v", err)
}

```

### Receiving Files

```go
ops := croc.Options{
    IsSender:      false,
    SharedSecret:  "my-secret-code",
}
client, err := croc.New(ops)
if err != nil {
    log.Fatalf("init error: %v", err)
}
if err := client.Receive(); err != nil {
    log.Fatalf("receive error: %v", err)
}

```

Both examples rely on the `New`, `Send`, and `Receive` functions defined in [`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go).

## Integration with the Croc Architecture

The [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) main client implementation orchestrates several specialized packages to provide its functionality. It utilizes **[`src/comm/comm.go`](https://github.com/schollz/croc/blob/main/src/comm/comm.go)** for low-level message framing over TCP, **[`src/tcp/tcp.go`](https://github.com/schollz/croc/blob/main/src/tcp/tcp.go)** for connection management and relay communication, and **[`src/crypt/crypt.go`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go)** for AES-GCM encryption of all payloads. Message types defined in **[`src/message/message.go`](https://github.com/schollz/croc/blob/main/src/message/message.go)** (including PAKE messages, file chunks, and EOF signals) flow through these channels, while **[`src/utils/utils.go`](https://github.com/schollz/croc/blob/main/src/utils/utils.go)** provides hashing, IP discovery, and clipboard utilities. Constants and defaults from **[`src/models/models.go`](https://github.com/schollz/croc/blob/main/src/models/models.go)** complete the stack, allowing [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) to function as the high-level entry point that binds these components into a cohesive file-transfer tool.

## Summary

- The **[`croc.go`](https://github.com/schollz/croc/blob/main/croc.go)** file serves as the primary orchestrator for the croc file-transfer tool, implementing the complete client lifecycle in `schollz/croc`.
- It manages configuration through the **`Options`** struct (lines 73-103), handling flags for relay addresses, throttling, and transfer direction.
- File discovery functions **`GetFilesInfo`** prepare transfer manifests while respecting exclusion patterns and computing integrity hashes.
- Security relies on PAKE key exchange implemented in **`senderWaitForHandshake`** and **`transfer`** (lines 143-151, 98-104), followed by AES-GCM encryption for all data.
- Fault tolerance is provided by **`transferWithReconnect`** and **`reconnectRelayAttempt`** (lines 56-65, 70-78), enabling automatic recovery from network interruptions.
- The client supports LAN-only transfers through **`setupLocalRelay`** and **`broadcastOnLocalNetwork`** (lines 29-33, 84-92) when internet relays are unavailable.
- User experience features include QR code generation, clipboard integration, and progress reporting via the **`Send`** method (lines 138-150).

## Frequently Asked Questions

### What is the purpose of the Options struct in croc.go?

The **`Options`** struct defined at lines 73-103 serves as the configuration container for all client operations. It aggregates CLI flags such as **`IsSender`**, **`RelayAddress`**, **`SharedSecret`**, and **`ThrottleUpload`**, providing type-safe access to user preferences throughout the transfer lifecycle.

### How does croc.go handle network interruptions during transfers?

The client implements resilient retry logic through **`transferWithReconnect`**, **`canRetryTransfer`**, and **`reconnectRelayAttempt`** (lines 56-65, 70-78). These methods automatically attempt to re-establish connections to the relay when disruptions occur, using bounded retry counts to balance persistence with resource conservation.

### What encryption standard does the croc.go client use?

After completing the PAKE handshake via **`senderWaitForHandshake`**, the client encrypts all subsequent traffic using **AES-GCM** as implemented in the [`src/crypt/crypt.go`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go) package. This symmetric encryption ensures that only parties possessing the shared secret can decrypt file chunks and metadata.

### How does croc.go discover which files to transfer?

The **`GetFilesInfo`** and **`GetFilesInfoWithExactExclusions`** functions (lines 63-71) recursively walk the specified paths, apply exclusion filters including **`.gitignore`** patterns when enabled, and generate **`FileInfo`** structures containing hashes and metadata. This discovery phase occurs before transmission to ensure the receiver receives an accurate file manifest.