Skip to content

Dev Docs Arch Protocols

Andy Lemin edited this page Aug 16, 2025 · 2 revisions

Protocol Stack Documentation

Network Protocol Architecture

Netatalk supports two distinct network protocol stacks for AFP communication, allowing it to serve both modern and legacy Mac clients.

Implementation Files:

  • DSI Protocol: libatalk/dsi/ - Data Stream Interface implementation for TCP/IP
  • ASP Protocol: libatalk/asp/ - AppleTalk Session Protocol implementation
  • AppleTalk Stack: libatalk/atp/, etc/atalkd/ - AppleTalk transport and routing
  • Protocol Headers: include/atalk/dsi.h, include/atalk/asp.h - Protocol constants and structures

AFP over TCP/IP (DSI Protocol)

Data Stream Interface (DSI)

DSI is the session layer protocol that carries AFP over TCP/IP connections. It provides:

  • Session Management: Connection establishment and teardown
  • Request/Response Framing: Message boundaries and sequencing
  • Flow Control: Data streaming and buffering
  • Error Handling: Connection recovery and error reporting

Implementation Files:

  • Core DSI Implementation: libatalk/dsi/dsi_stream.c - Main DSI protocol engine
  • TCP Transport: libatalk/dsi/dsi_tcp.c - TCP socket handling and network I/O
  • Connection Management: libatalk/dsi/dsi_init.c - DSI session initialization and cleanup
  • Command Processing: libatalk/dsi/dsi_cmdreply.c - Command/reply message handling
  • Attention Handling: libatalk/dsi/dsi_attn.c - Server attention message processing

DSI Message Format

The DSI protocol uses a fixed 16-byte header for all messages:

Implementation Files:

  • Header Definitions: include/atalk/dsi.h - DSI message format constants and structures
  • Header Processing: libatalk/dsi/dsi_stream.c - DSI header parsing and construction
  • Network Byte Order: libatalk/dsi/dsi_tcp.c - Endianness handling for network transmission
#define DSI_BLOCKSIZ 16
struct dsi_block {
    uint8_t dsi_flags;       /* packet type: request or reply */
    uint8_t dsi_command;     /* command */
    uint16_t dsi_requestID;  /* request ID */
    union {
        uint32_t dsi_code;   /* error code */
        uint32_t dsi_doff;   /* data offset */
    } dsi_data;
    uint32_t dsi_len;        /* total data length */
    uint32_t dsi_reserved;   /* reserved field */
};

Header Layout (Network Byte Order):

DSI Header (16 bytes):
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|FL|CM|     REQUEST ID        |  DATA OFFSET/CODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|           TOTAL DATA LENGTH                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                 RESERVED                        |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

FL = Flags: DSIFL_REQUEST (0x00) or DSIFL_REPLY (0x01)
CM = Command (1 byte)
REQUEST ID = Request identifier (2 bytes, network order)
DATA OFFSET/CODE = Data offset (requests) or error code (replies) (4 bytes)
TOTAL DATA LENGTH = Total message length (4 bytes, network order)
RESERVED = Reserved field (4 bytes)

DSI Commands

Command Value Description
DSIFUNC_CLOSE 1 Close the DSI session
DSIFUNC_CMD 2 AFP command request
DSIFUNC_STAT 3 Get server status
DSIFUNC_OPEN 4 Open new DSI session
DSIFUNC_TICKLE 5 Keep-alive message
DSIFUNC_WRITE 6 Write data to server
DSIFUNC_ATTN 8 Server attention message

DSI Error Codes

Error Value Description
DSIERR_OK 0x0000 Success
DSIERR_BADVERS 0xfbd6 Bad version
DSIERR_BUFSMALL 0xfbd5 Buffer too small
DSIERR_NOSESS 0xfbd4 No session
DSIERR_NOSERV 0xfbd3 No server
DSIERR_PARM 0xfbd2 Parameter error
DSIERR_SERVBUSY 0xfbd1 Server busy
DSIERR_SESSCLOS 0xfbd0 Session closed
DSIERR_SIZERR 0xfbcf Size error
DSIERR_TOOMANY 0xfbce Too many connections

DSI Session Options

Option Value Description
DSIOPT_SERVQUANT 0x00 Server request quantum
DSIOPT_ATTNQUANT 0x01 Attention quantum
DSIOPT_REPLCSIZE 0x02 AFP replaycache size

Quantum Configuration:

  • Default server quantum: 1MB (DSI_SERVQUANT_DEF = 0x100000L)
  • Minimum server quantum: 32KB (DSI_SERVQUANT_MIN = 32000)
  • Maximum server quantum: 4GB (DSI_SERVQUANT_MAX = 0xffffffff)
  • Default attention quantum: 2 (DSI_DEFQUANT = 2)

End-to-End Multi-Layer Buffering Architecture

The DSI implementation uses a sophisticated 4-layer buffering system from network to filesystem that is critical for performance and debugging:

Implementation Files:

  • Buffer Management: libatalk/dsi/dsi_stream.c - Core buffering logic and read-ahead management
  • Socket Buffers: libatalk/dsi/dsi_tcp.c - TCP socket buffer configuration (SO_RCVBUF/SO_SNDBUF)
  • DSI Buffers: include/atalk/dsi.h - DSI buffer structure definitions (DSI_DATASIZ, etc.)
  • Flow Control: libatalk/dsi/dsi_stream.c - dsi_peek() and buffer space management
  • Configuration: etc/afpd/afp_config.c - dsireadbuf and quantum configuration parsing
graph TB
    subgraph "Network Layer"
        A[TCP Socket Buffer<br/>Kernel managed]
        B[Socket Receive Buffer<br/>SO_RCVBUF]
        C[Socket Send Buffer<br/>SO_SNDBUF]
    end
    
    subgraph "DSI Stream Layer"
        D[DSI Read Buffer<br/>dsi->buffer to dsi->end<br/>Configurable via -dsireadbuf]
        E[DSI Command Buffer<br/>dsi->commands<br/>Receives DSI headers]
        F[DSI Data Buffer<br/>dsi->data array DSI_DATASIZ<br/>64KB reply buffer]
    end
    
    subgraph "DSI Buffer Management"
        G[Read-ahead Pointers<br/>start, eof, buffer, end]
        H[Quantum Control<br/>server_quantum: 32KB-4GB<br/>Default: 1MB]
        I[Flow Control<br/>dsi_peek and select logic]
    end
    
    subgraph "AFP Command Layer"
        J[AFP Command Processing<br/>afp_* functions]
        K[Volume Operations<br/>File/Directory operations]
    end
    
    subgraph "VFS/Filesystem"
        L[VFS Buffer Cache<br/>Kernel page cache]
        M[Disk I/O<br/>Physical storage]
    end
    
    A --> D
    B --> D
    D --> G
    G --> E
    E --> J
    J --> K
    K --> L
    L --> M
    
    F --> C
    C --> A
    
    H -.-> D
    H -.-> F
    I -.-> G
Loading

DSI Quantum Management and Flow Control Pipeline

The DSI layer implements sophisticated flow control to prevent buffer overruns and optimize performance:

sequenceDiagram
    participant Client as Mac Client
    participant TCP as TCP Layer
    participant DSI as DSI Stream Layer
    participant Buf as Buffer Manager
    participant AFP as AFP Layer
    
    Note over Client,AFP: DSI Session Establishment with Quantum Negotiation
    Client->>DSI: OpenSession (request quantum)
    DSI->>Client: Server Quantum: 1MB (default)
    
    Note over Client,AFP: Large File Transfer with Flow Control
    Client->>TCP: Large AFP Write Request
    TCP->>DSI: Data chunks
    DSI->>Buf: Check buffer space (dsi_peek)
    
    alt Buffer has space
        Buf->>DSI: Read into dsi->buffer
        DSI->>AFP: Process command
    else Buffer full (dsi->eof >= dsi->end)
        Buf->>DSI: Log "readahead buffer full"
        DSI->>Buf: Wait for space (select)
        Buf->>DSI: Buffer space available
    end
    
    AFP->>DSI: Response data
    DSI->>Buf: Fill reply buffer (64KB chunks)
    Buf->>TCP: Send via writev() coalescing
    TCP->>Client: Response chunks
    
    Note over DSI: TCP_NODELAY for small packets
    Note over Buf: Signal blocking during writes
Loading

Enhanced DSI State Machine with Buffer Integration

The DSI implementation maintains 9 sophisticated state flags that interact with buffer management:

stateDiagram-v2
    [*] --> Closed
    
    state "DSI Protocol States" as DSI {
        Closed --> Connected: TCP Connect
        Connected --> SessionOpen: DSI OpenSession
        SessionOpen --> DataReceived: DSI_DATA flag set
        DataReceived --> AFPRunning: DSI_RUNNING flag set
        AFPRunning --> DataReceived: More commands
    }
    
    state "Buffer Management States" as Buf {
        BufferEmpty --> BufferFilling: dsi_stream_read()
        BufferFilling --> BufferReady: Data available
        BufferReady --> BufferProcessing: AFP command
        BufferProcessing --> BufferEmpty: Command complete
        BufferReady --> BufferFull: dsi->eof >= dsi->end
        BufferFull --> BufferReady: Space available
    }
    
    state "Advanced Connection States" as Advanced {
        AFPRunning --> Sleeping: DSI_SLEEPING (FPZzz)
        AFPRunning --> ExtSleeping: DSI_EXTSLEEP
        AFPRunning --> NoReply: DSI_NOREPLY (streaming)
        AFPRunning --> Disconnected: DSI_DISCONNECTED
        AFPRunning --> Dying: DSI_DIE (SIGUSR1)
        AFPRunning --> LoggedOut: DSI_AFP_LOGGED_OUT
        AFPRunning --> Reconnecting: DSI_RECONSOCKET
        AFPRunning --> ReconInProgress: DSI_RECONINPROG
    }
    
    DSI --> Buf: Buffer operations
    DSI --> Advanced: State transitions
    
    Sleeping --> AFPRunning: Wake up
    ExtSleeping --> AFPRunning: Extended wake
    NoReply --> AFPRunning: Stream complete
    Disconnected --> [*]: Connection lost
    Dying --> [*]: Graceful shutdown
    LoggedOut --> Closed: Client logout
    Reconnecting --> AFPRunning: New socket
    ReconInProgress --> AFPRunning: Reconnect complete
Loading

Performance Optimization Architecture

The DSI implementation includes sophisticated optimizations critical for Mac client performance:

graph TB
    subgraph "Network Optimizations"
        A[TCP_NODELAY<br/>Disable Nagle algorithm<br/>Essential for Mac responsiveness]
        B[writev Coalescing<br/>Combine DSI header + data<br/>Reduce system calls]
        C[Socket Buffer Tuning<br/>SO_RCVBUF/SO_SNDBUF<br/>Match quantum sizes]
    end
    
    subgraph "DSI Buffer Optimizations"
        D[Read-ahead Buffering<br/>dsireadbuf configuration<br/>Prevents excessive reads]
        E[Quantum Management<br/>1MB default, 32KB-4GB range<br/>Network condition tuning]
        F[Zero-copy Pointers<br/>start/eof/end management<br/>Minimize data copying]
    end
    
    subgraph "Signal Safety Architecture"
        G[Atomic Write Protection<br/>SIG_BLOCK during transfers<br/>Prevents corruption]
        H[Tickle Suppression<br/>SIGALRM disabled during<br/>large file transfers]
        I[Attention Buffer Isolation<br/>Separate buffers for<br/>SIGHUP/SIGTERM handlers]
    end
    
    subgraph "AFP Layer Integration"
        J[Streaming Read Pipeline<br/>dsi_readinit/dsi_read<br/>Large file optimization]
        K[Partial Packet Handling<br/>dsi_write incomplete<br/>packet management]
        L[Sendfile Integration<br/>Zero-copy reads when<br/>available if compiled with sendfile support]
    end
    
    A --> D
    B --> E
    C --> F
    D --> G
    E --> H
    F --> I
    G --> J
    H --> K
    I --> L
Loading

Detailed Read/Write Pipeline with Buffer Flow

Shows the complete data path through all buffering layers for performance analysis:

sequenceDiagram
    participant Mac as Mac Client
    participant Net as TCP Network
    participant DSI as DSI Layer
    participant Buf as Buffer Manager
    participant Disk as Filesystem
    
    Note over Mac,Disk: Write Pipeline (Client → Server → Disk)
    
    Mac->>Net: AFP Write + Data Stream
    Net->>DSI: TCP segments
    DSI->>Buf: dsi_stream_receive()
    Buf->>DSI: Fill read-ahead buffer (dsireadbuf)
    DSI->>DSI: Parse 16-byte DSI header
    DSI->>Buf: dsi_writeinit(buflen, datasize)
    
    loop Transfer Loop (until datasize = 0)
        Buf->>DSI: dsi_write() - extract buffered data
        DSI->>Disk: Write data chunk to file
        Disk-->>DSI: Write acknowledgment
        DSI->>Buf: Update remaining datasize counter
    end
    
    DSI->>Buf: dsi_writeflush() - clear remaining buffers
    DSI->>Net: Send AFP success response
    Net->>Mac: Transfer complete
    
    Note over Mac,Disk: Read Pipeline (Server → Client)
    
    Mac->>DSI: AFP Read Request
    DSI->>Disk: Read file data
    Disk-->>DSI: File content
    DSI->>Buf: dsi_readinit() - setup streaming transfer
    DSI->>Net: Send DSI header + initial data
    
    loop Streaming Loop (quantum-limited)
        DSI->>Buf: dsi_read() - get next chunk
        Buf->>Net: Stream via quantum-sized chunks
        Net->>Mac: Data delivery
        DSI->>Buf: Update transfer progress
    end
    
    DSI->>Buf: dsi_readdone() - cleanup transfer state
Loading

TCP Connection Management

sequenceDiagram
    participant Client as Mac Client
    participant Server as afpd
    
    Client->>Server: TCP SYN (port 548)
    Server-->>Client: TCP SYN-ACK
    Client->>Server: TCP ACK
    
    Client->>Server: DSI OpenSession
    Server-->>Client: DSI OpenSession Reply
    
    loop AFP Operations
        Client->>Server: DSI Command (AFP Request)
        Server-->>Client: DSI Command Reply (AFP Response)
    end
    
    Client->>Server: DSI CloseSession
    Server-->>Client: DSI CloseSession Reply
    
    Client->>Server: TCP FIN
    Server-->>Client: TCP FIN-ACK
Loading

DSI Performance Tuning Guidelines

Critical Buffer Configuration

Read-ahead Buffer Size (-dsireadbuf option):

  • Default: System-dependent, typically 16KB-32KB
  • Recommended: Match or exceed server quantum (1MB default)
  • Symptoms of undersized buffer: "readahead buffer is full" log messages
  • Large file transfers: Increase to 2-4MB for optimal performance

Server Quantum Configuration:

  • Default: 1MB (DSI_SERVQUANT_DEF = 0x100000L)
  • Range: 32KB (DSI_SERVQUANT_MIN) to 4GB (DSI_SERVQUANT_MAX)
  • Network optimization: Match network MTU and latency characteristics
  • High-latency links: Increase quantum size to reduce round trips

Implementation Files:

  • Buffer Configuration: etc/afpd/afp_config.c - dsireadbuf parsing and validation
  • Quantum Management: libatalk/dsi/dsi_stream.c - Quantum negotiation and enforcement
  • Performance Constants: include/atalk/dsi.h - DSI_SERVQUANT_* definitions
  • Buffer Monitoring: libatalk/dsi/dsi_stream.c - Buffer fullness logging and warnings

Performance Monitoring

Buffer utilization indicators:

# Monitor DSI buffer warnings in logs
grep "readahead buffer is full" /var/log/afpd.log

# Check quantum negotiation
grep "DSI quantum" /var/log/afpd.log

# Monitor connection state changes
grep "DSI_.*:" /var/log/afpd.log

Key performance metrics:

  • Buffer overruns: Frequency of "buffer is full" warnings
  • Quantum efficiency: Data throughput vs configured quantum size
  • State transition frequency: Excessive DSI_DISCONNECTED events
  • Signal handler interference: Write interruption patterns

AFP over AppleTalk (ASP Protocol)

AppleTalk Session Protocol (ASP)

ASP provides session services over the AppleTalk protocol suite:

  • Session Management: ATP-based reliable sessions
  • Request Queuing: Multiple outstanding requests
  • Status Monitoring: Server status broadcasts
  • Error Recovery: Automatic retry mechanisms

Implementation Files:

  • ASP Implementation: libatalk/asp/asp_getsess.c - ASP session management
  • ATP Transport: libatalk/atp/atp_open.c - AppleTalk Transaction Protocol
  • Session State: libatalk/asp/asp_proto.c - ASP protocol state machine
  • Status Broadcasting: etc/afpd/status.c - Server status information via ASP
  • Header Definitions: include/atalk/asp.h - ASP protocol constants and structures

AppleTalk Protocol Stack

Application Layer:     AFP (Apple Filing Protocol)
Session Layer:         ASP (AppleTalk Session Protocol)
Transport Layer:       ATP (AppleTalk Transaction Protocol)
Network Services:      RTMP, NBP, ZIP, AEP
Network Layer:         DDP (Datagram Delivery Protocol)
Data Link Layer:       LocalTalk, EtherTalk, TokenTalk

Implementation Files:

  • ATP Layer: libatalk/atp/ - AppleTalk Transaction Protocol implementation
  • DDP Layer: etc/atalkd/ddp.c - Datagram Delivery Protocol handling
  • RTMP: etc/atalkd/rtmp.c - Routing Table Maintenance Protocol
  • NBP: etc/atalkd/nbp.c - Name Binding Protocol implementation
  • ZIP: etc/atalkd/zip.c - Zone Information Protocol
  • AppleTalk Daemon: etc/atalkd/main.c - AppleTalk routing daemon

AppleTalk Network Architecture

graph TB
    subgraph "AppleTalk Internetwork"
        subgraph "Network 1000-1000"
            A[Mac Client<br/>1000.10]
            B[Netatalk Server<br/>1000.50]
        end
        
        subgraph "Network 2000-2000"
            C[Mac Client<br/>2000.25]
            D[LaserWriter<br/>2000.100]
        end
        
        E[AppleTalk Router]
    end
    
    A -.-> B
    C -.-> E
    E -.-> B
    C -.-> D
Loading

NBP (Name Binding Protocol)

NBP provides name-to-address resolution in AppleTalk networks:

NBP Tuple Format: object:type@zone
Examples:
- MyServer:AFPServer@Engineering
- LaserWriter:LaserWriter@*
- TimeLord:TimeLord@Engineering

Implementation Files:

  • NBP Implementation: etc/atalkd/nbp.c - Name binding protocol engine
  • NBP Utilities: bin/nbp/nbplkup.c - NBP lookup utilities and tools
  • Name Registration: etc/afpd/status.c - AFP server NBP registration
  • Header Definitions: include/atalk/nbp.h - NBP protocol constants

Zone Information Protocol (ZIP)

ZIP manages AppleTalk network zones:

  • Zone Lists: Maintains network-to-zone mappings
  • Zone Information: Provides zone names for networks
  • GetZoneList: Client discovery of available zones

Implementation Files:

  • ZIP Implementation: etc/atalkd/zip.c - Zone Information Protocol engine
  • Zone Management: etc/atalkd/config.c - Zone configuration parsing
  • Network Mapping: etc/atalkd/rtmp.c - Network-to-zone relationship management
  • Header Definitions: include/atalk/zip.h - ZIP protocol constants

AFP Protocol Layer

AFP Commands

AFP defines over 100 commands organized into functional categories:

Implementation Files:

  • Command Definitions: include/atalk/afp.h - Complete AFP command constants and structures
  • Command Dispatch: etc/afpd/switch.c - AFP command routing and execution table
  • Server Commands: etc/afpd/status.c - FPGetSrvrInfo and server capability implementation
  • Session Commands: etc/afpd/auth.c - FPLogin, FPLogout, and authentication handling
  • Volume Commands: etc/afpd/volume.c - FPOpenVol, FPCloseVol, and volume management
  • Directory Commands: etc/afpd/directory.c - Directory manipulation command implementations
  • File Commands: etc/afpd/file.c - File operation command implementations
  • Fork Commands: etc/afpd/fork.c - Fork (data/resource) handling implementations

Server Commands

  • FPGetSrvrInfo: Get server capabilities and version
  • FPGetSrvrParms: Get server parameters
  • FPGetSrvrMsg: Get server message

Session Commands

  • FPLogin: Authenticate user session
  • FPLoginExt: Extended authentication
  • FPLogout: End user session
  • FPMapID: Map user/group IDs
  • FPMapName: Map user/group names

Volume Commands

  • FPOpenVol: Open volume for access
  • FPCloseVol: Close volume
  • FPGetVolParms: Get volume parameters
  • FPSetVolParms: Set volume parameters

Directory Commands

  • FPOpenDir: Open directory
  • FPCloseDir: Close directory
  • FPCreateDir: Create directory
  • FPDelete: Delete file or directory
  • FPGetFileDirParms: Get file/directory parameters
  • FPSetFileDirParms: Set file/directory parameters
  • FPEnumerate: Enumerate directory contents

File Commands

  • FPOpenFork: Open file fork
  • FPCloseFork: Close file fork
  • FPCreateFile: Create new file
  • FPRead: Read from file
  • FPWrite: Write to file
  • FPFlush: Flush file data
  • FPGetForkParms: Get fork parameters
  • FPSetForkParms: Set fork parameters

AFP Data Types

File and Directory IDs

typedef uint32_t AFPDir;     // Directory ID
typedef uint32_t AFPFile;    // File ID
typedef uint16_t AFPFork;    // Fork reference number

Volume and Server Info

struct AFPVolParms {
    uint16_t    vp_attr;        // Volume attributes
    uint16_t    vp_sig;         // Volume signature
    uint32_t    vp_cdate;       // Creation date
    uint32_t    vp_mdate;       // Modification date
    uint32_t    vp_bdate;       // Backup date
    uint16_t    vp_vid;         // Volume ID
    uint32_t    vp_bytes_free;  // Free bytes
    uint32_t    vp_bytes_total; // Total bytes
    uint8_t     vp_name[28];    // Volume name
};

Protocol Implementation Details

DSI Connection Structure

The complete DSI connection structure provides sophisticated connection management:

#define DSI_DATASIZ 65536

typedef struct DSI {
    struct DSI *next;             /* multiple listening addresses */
    AFPObj   *AFPobj;            /* back-reference to AFP object */
    
    // Server identification
    int      statuslen;
    char     status[1400];       /* server status block */
    char     *signature;         /* server signature */
    
    // Protocol header and addressing
    struct dsi_block        header;
    struct sockaddr_storage server, client;
    struct itimerval        timer;
    
    // Connection state management
    int      tickle;            /* tickle count for keepalive */
    int      in_write;          /* write operation in progress */
    int      msg_request;       /* pending message to client */
    int      down_request;      /* pending shutdown request */
    
    // Performance and flow control
    uint32_t attn_quantum;      /* attention quantum size */
    uint32_t datasize;          /* current data size */
    uint32_t server_quantum;    /* server quantum size */
    uint16_t serverID, clientID; /* connection identifiers */
    
    // I/O buffers
    uint8_t  *commands;         /* DSI receive buffer */
    uint8_t  data[DSI_DATASIZ]; /* DSI reply buffer (64KB) */
    size_t   datalen, cmdlen;   /* buffer lengths */
    off_t    read_count, write_count; /* I/O statistics */
    
    // Connection management
    uint32_t flags;             /* DSI state flags */
    int      socket;            /* AFP session socket */
    int      serversock;        /* listening socket (-1 for client connections) */
    
    // Advanced buffering system
    size_t   dsireadbuf;        /* DSI readahead buffer size */
    char     *buffer;           /* buffer start */
    char     *start;            /* current buffer head */
    char     *eof;              /* end of currently used buffer */
    char     *end;              /* buffer end */
    
#ifdef USE_ZEROCONF
    char *bonjourname;          /* Bonjour service name */
    int zeroconf_registered;    /* Zeroconf registration status */
#endif
    
    // Protocol-specific function pointers
    pid_t (*proto_open)(struct DSI *);
    void (*proto_close)(struct DSI *);
} DSI;

DSI State Management

The DSI implementation uses comprehensive state flags:

/* DSI session State flags */
#define DSI_DATA             (1 << 0) /* received a DSI command */
#define DSI_RUNNING          (1 << 1) /* received an AFP command */
#define DSI_SLEEPING         (1 << 2) /* sleeping after FPZzz */
#define DSI_EXTSLEEP         (1 << 3) /* extended sleep mode */
#define DSI_DISCONNECTED     (1 << 4) /* disconnected state after socket error */
#define DSI_DIE              (1 << 5) /* SIGUSR1, shutting down in 5 minutes */
#define DSI_NOREPLY          (1 << 6) /* generate own replies in dsi_write */
#define DSI_RECONSOCKET      (1 << 7) /* new socket from primary reconnect */
#define DSI_RECONINPROG      (1 << 8) /* reconnection in progress */
#define DSI_AFP_LOGGED_OUT   (1 << 9) /* client called afp_logout */

Advanced DSI Features

Readahead Buffering System: The DSI implementation includes sophisticated buffering for performance:

  • Configurable readahead buffer size (dsireadbuf)
  • Smart buffer management with start, eof, and end pointers
  • Efficient dsi_peek() operations for protocol parsing

Zero-Copy Operations:

#ifdef WITH_SENDFILE
extern ssize_t dsi_stream_read_file(DSI *, int, off_t off, const size_t len, const int err);
#endif

Service Discovery Integration:

  • Bonjour/Zeroconf service registration
  • UTF-8 service name support
  • Automatic service discovery for Mac clients

Connection Multiplexing:

  • Multiple listening addresses support (next pointer for address chaining)
  • Per-connection AFP object association
  • Efficient connection pooling and management

AppleTalk Address Resolution

// AppleTalk network address
struct at_addr {
    uint16_t s_net;              // Network number
    uint8_t  s_node;             // Node number
};

// NBP name tuple
struct nbptuple {
    char object[32];             // Object name
    char type[32];               // Service type  
    char zone[32];               // Zone name
};

Error Handling

Both protocol stacks implement comprehensive error handling:

AFP Error Codes

  • AFPNoErr (0): No error
  • AFPASPSessClosed (-1072): ASP session closed
  • AFPUserNotAuth (-5023): User not authenticated
  • AFPVolLocked (-5006): Volume locked
  • AFPDirNotEmpty (-5013): Directory not empty
  • AFPFileBusy (-5016): File busy
  • AFPAccessDenied (-5000): Access denied

DSI Error Recovery

  • Connection timeout: Automatic reconnection
  • Request timeout: Command retry with backoff
  • Socket errors: Connection re-establishment
  • Protocol errors: Session reset

AppleTalk Error Recovery

  • ATP timeout: Automatic retry with exponential backoff
  • Network unreachable: Route rediscovery
  • Name lookup failure: NBP retry sequence
  • Zone information stale: ZIP refresh

Performance Characteristics

TCP/IP (DSI) Performance

  • Throughput: Limited by TCP window size and network bandwidth
  • Latency: Single round-trip per AFP command
  • Concurrency: Multiple TCP connections supported
  • Optimization: TCP_NODELAY, large buffers, sendfile() usage

AppleTalk (ASP) Performance

  • Throughput: Limited by ATP packet size (578 bytes max)
  • Latency: Multiple round-trips for large operations
  • Concurrency: Limited by ATP socket availability
  • Optimization: Packet coalescing, request pipelining

This protocol documentation provides the foundation for understanding how Netatalk communicates with Mac clients across different network configurations and Mac generations.

Clone this wiki locally