Skip to content

Dev Docs Arch Protocols

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

WIP - ALL LINKS IN THIS WIKI STRUCTURE ARE CURRENTLY BROKEN DURING WIKI MIGRATION

THESE ARE COMMUNITY DOCS

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