netatalk  4.4.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
dsi.h File Reference

DSI (Data Stream Interface) protocol definitions. More...

#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <atalk/afp.h>
#include <atalk/globals.h>
#include <atalk/server_child.h>

Go to the source code of this file.

Data Structures

struct  dsi_block
struct  DSI

Macros

#define DSI_BLOCKSIZ   16
#define DSI_DATASIZ   65536
#define DSIFL_REQUEST   0x00
#define DSIFL_REPLY   0x01
#define DSIFL_MAX   0x01
#define DSIOPT_SERVQUANT   0x00
#define DSIOPT_ATTNQUANT   0x01
#define DSIOPT_REPLCSIZE   0x02
#define DSIFUNC_CLOSE   1
#define DSIFUNC_CMD   2
#define DSIFUNC_STAT   3
#define DSIFUNC_OPEN   4
#define DSIFUNC_TICKLE   5
#define DSIFUNC_WRITE   6
#define DSIFUNC_ATTN   8
#define DSIFUNC_MAX   8
#define DSIERR_OK   0x0000
#define DSIERR_BADVERS   0xfbd6
#define DSIERR_BUFSMALL   0xfbd5
#define DSIERR_NOSESS   0xfbd4
#define DSIERR_NOSERV   0xfbd3
#define DSIERR_PARM   0xfbd2
#define DSIERR_SERVBUSY   0xfbd1
#define DSIERR_SESSCLOS   0xfbd0
#define DSIERR_SIZERR   0xfbcf
#define DSIERR_TOOMANY   0xfbce
#define DSIERR_NOACK   0xfbcd
#define DSI_DEFQUANT   2
#define DSI_SERVQUANT_MAX   0xffffffff
#define DSI_SERVQUANT_MIN   32000
#define DSI_SERVQUANT_DEF   0x100000L
#define DSI_AFPOVERTCP_PORT   548
#define DSI_DATA   (1 << 0)
#define DSI_RUNNING   (1 << 1)
#define DSI_SLEEPING   (1 << 2)
#define DSI_EXTSLEEP   (1 << 3)
#define DSI_DISCONNECTED   (1 << 4)
#define DSI_DIE   (1 << 5)
#define DSI_NOREPLY   (1 << 6)
#define DSI_RECONSOCKET   (1 << 7)
#define DSI_RECONINPROG   (1 << 8)
#define DSI_AFP_LOGGED_OUT   (1 << 9)
#define DSI_NOWAIT   1
#define DSI_MSG_MORE   2
#define dsi_wrtreply(a, b)
#define dsi_serverID(x)
#define dsi_send(x)

Typedefs

typedef struct DSI DSI

Functions

DSIdsi_init (AFPObj *obj, const char *hostname, const char *address, const char *port)
void dsi_setstatus (DSI *, char *, const size_t)
int dsi_tcp_init (DSI *dsi, const char *hostname, const char *address, const char *port)
 Initialize DSI over TCP.
void dsi_free (DSI *dsi)
int dsi_getsession (DSI *, server_child_t *, const int, afp_child_t **)
 Start a DSI session, fork an afpd process.
void dsi_kill (int)
void dsi_opensession (DSI *)
int dsi_attention (DSI *, AFPUserBytes)
 send an attention.
int dsi_cmdreply (DSI *, const int)
int dsi_tickle (DSI *)
void dsi_getstatus (DSI *)
void dsi_close (DSI *)
ssize_t dsi_stream_write (DSI *, void *, const size_t, const int mode)
 write raw DSI data
size_t dsi_stream_read (DSI *, void *, const size_t)
 Read data from DSI buffer.
int dsi_stream_send (DSI *, void *, size_t)
 write data.
int dsi_stream_receive (DSI *)
 Read DSI command and data.
int dsi_disconnect (DSI *dsi)
 Communication error with the client, enter disconnected state.
ssize_t dsi_stream_read_file (DSI *, int, off_t off, const size_t len, const int err)
size_t dsi_writeinit (DSI *, void *, const size_t)
size_t dsi_write (DSI *, void *, const size_t)
void dsi_writeflush (DSI *)
ssize_t dsi_readinit (DSI *, void *, const size_t, const size_t, const int)
 streaming i/o for afp_read.
ssize_t dsi_read (DSI *, void *, const size_t)
void dsi_readdone (DSI *)

Detailed Description

DSI (Data Stream Interface) protocol definitions.

What a DSI packet looks like:

0 32
|-------------------------------|
|flags |command| requestID |
|-------------------------------|
|error code/enclosed data offset|
|-------------------------------|
|total data length |
|-------------------------------|
|reserved field |
|-------------------------------|
static dbd_flags_t flags
Definition cmd_dbd.c:45
#define data
Definition hash.c:37
Note
CONVENTION: anything with a dsi_ prefix is kept in network byte order.

Macro Definition Documentation

◆ DSI_AFP_LOGGED_OUT

#define DSI_AFP_LOGGED_OUT   (1 << 9)

client called afp_logout, quit on next EOF from socket

◆ DSI_AFPOVERTCP_PORT

#define DSI_AFPOVERTCP_PORT   548

default port number

◆ DSI_BLOCKSIZ

#define DSI_BLOCKSIZ   16

◆ DSI_DATA

#define DSI_DATA   (1 << 0)

we have received a DSI command

◆ DSI_DATASIZ

#define DSI_DATASIZ   65536

◆ DSI_DEFQUANT

#define DSI_DEFQUANT   2

default attention quantum size

◆ DSI_DIE

#define DSI_DIE   (1 << 5)

SIGUSR1, going down in 5 minutes

◆ DSI_DISCONNECTED

#define DSI_DISCONNECTED   (1 << 4)

we're in diconnected state after a socket error

◆ DSI_EXTSLEEP

#define DSI_EXTSLEEP   (1 << 3)

we're sleeping after FPZzz

◆ DSI_MSG_MORE

#define DSI_MSG_MORE   2

◆ DSI_NOREPLY

#define DSI_NOREPLY   (1 << 6)

in dsi_write we generate our own replies

◆ DSI_NOWAIT

#define DSI_NOWAIT   1

◆ DSI_RECONINPROG

#define DSI_RECONINPROG   (1 << 8)

used in the new session in reconnect

◆ DSI_RECONSOCKET

#define DSI_RECONSOCKET   (1 << 7)

we have a new socket from primary reconnect

◆ DSI_RUNNING

#define DSI_RUNNING   (1 << 1)

we have received a AFP command

◆ dsi_send

#define dsi_send ( x)
Value:
do { \
(x)->header.dsi_len = htonl((x)->cmdlen); \
dsi_stream_send((x), (x)->commands, (x)->cmdlen); \
} while (0)
static void header(void)
Definition speedtest.c:570

◆ dsi_serverID

#define dsi_serverID ( x)
Value:
((x)->serverID++)

◆ DSI_SERVQUANT_DEF

#define DSI_SERVQUANT_DEF   0x100000L

default server quantum (1 MB)

◆ DSI_SERVQUANT_MAX

#define DSI_SERVQUANT_MAX   0xffffffff

server quantum

◆ DSI_SERVQUANT_MIN

#define DSI_SERVQUANT_MIN   32000

minimum server quantum

◆ DSI_SLEEPING

#define DSI_SLEEPING   (1 << 2)

we're sleeping after FPZzz

◆ dsi_wrtreply

#define dsi_wrtreply ( a,
b )
Value:
int dsi_cmdreply(DSI *, const int)
Definition dsi_cmdreply.c:19

◆ DSIERR_BADVERS

#define DSIERR_BADVERS   0xfbd6

◆ DSIERR_BUFSMALL

#define DSIERR_BUFSMALL   0xfbd5

◆ DSIERR_NOACK

#define DSIERR_NOACK   0xfbcd

◆ DSIERR_NOSERV

#define DSIERR_NOSERV   0xfbd3

◆ DSIERR_NOSESS

#define DSIERR_NOSESS   0xfbd4

◆ DSIERR_OK

#define DSIERR_OK   0x0000

◆ DSIERR_PARM

#define DSIERR_PARM   0xfbd2

◆ DSIERR_SERVBUSY

#define DSIERR_SERVBUSY   0xfbd1

◆ DSIERR_SESSCLOS

#define DSIERR_SESSCLOS   0xfbd0

◆ DSIERR_SIZERR

#define DSIERR_SIZERR   0xfbcf

◆ DSIERR_TOOMANY

#define DSIERR_TOOMANY   0xfbce

◆ DSIFL_MAX

#define DSIFL_MAX   0x01

◆ DSIFL_REPLY

#define DSIFL_REPLY   0x01

◆ DSIFL_REQUEST

#define DSIFL_REQUEST   0x00

◆ DSIFUNC_ATTN

#define DSIFUNC_ATTN   8

DSIAttention

◆ DSIFUNC_CLOSE

#define DSIFUNC_CLOSE   1

DSICloseSession

◆ DSIFUNC_CMD

#define DSIFUNC_CMD   2

DSICommand

◆ DSIFUNC_MAX

#define DSIFUNC_MAX   8

largest command

◆ DSIFUNC_OPEN

#define DSIFUNC_OPEN   4

DSIOpenSession

◆ DSIFUNC_STAT

#define DSIFUNC_STAT   3

DSIGetStatus

◆ DSIFUNC_TICKLE

#define DSIFUNC_TICKLE   5

DSITickle

◆ DSIFUNC_WRITE

#define DSIFUNC_WRITE   6

DSIWrite

◆ DSIOPT_ATTNQUANT

#define DSIOPT_ATTNQUANT   0x01

attention quantum

◆ DSIOPT_REPLCSIZE

#define DSIOPT_REPLCSIZE   0x02

AFP replaycache size supported by the server (that's us)

◆ DSIOPT_SERVQUANT

#define DSIOPT_SERVQUANT   0x00

server request quantum

Typedef Documentation

◆ DSI

typedef struct DSI DSI

Function Documentation

◆ dsi_attention()

int dsi_attention ( DSI * dsi,
AFPUserBytes flags )
extern

send an attention.

Note
this may get called at any time, so we can't use DSI buffers to send one.
Returns
0 on error

◆ dsi_close()

void dsi_close ( DSI * dsi)
extern

◆ dsi_cmdreply()

int dsi_cmdreply ( DSI * dsi,
const int err )
extern

◆ dsi_disconnect()

int dsi_disconnect ( DSI * dsi)
extern

Communication error with the client, enter disconnected state.

  1. close the socket
  2. set the DSI_DISCONNECTED flag, remove possible sleep flags
Returns
0 if successfully entered disconnected state
-1 if ppid is 1 which means afpd master died, or euid == 0 i.e. where still running as root (unauthenticated session)

◆ dsi_free()

void dsi_free ( DSI * dsi)
extern

Free any allocated resources of the master afpd DSI objects and close server socket

◆ dsi_getsession()

int dsi_getsession ( DSI * dsi,
server_child_t * serv_children,
int tickleval,
afp_child_t ** childp )
extern

Start a DSI session, fork an afpd process.

Parameters
[in,out]dsiDSI structure
[in,out]serv_childrenpointer to our structure with all childs
[in]ticklevaltickle interval in seconds
[out]childpafter fork: parent return pointer to child, child returns NULL
Returns
0 on success, any other value denotes failure

◆ dsi_getstatus()

void dsi_getstatus ( DSI * dsi)
extern

◆ dsi_init()

DSI * dsi_init ( AFPObj * obj,
const char * hostname,
const char * address,
const char * port )
extern

◆ dsi_kill()

void dsi_kill ( int )
extern

◆ dsi_opensession()

void dsi_opensession ( DSI * dsi)
extern

OpenSession. set up the connection

◆ dsi_read()

ssize_t dsi_read ( DSI * dsi,
void * buf,
const size_t buflen )
extern

send off the data

◆ dsi_readdone()

void dsi_readdone ( DSI * dsi)
extern

◆ dsi_readinit()

ssize_t dsi_readinit ( DSI * dsi,
void * buf,
const size_t buflen,
const size_t size,
const int err )
extern

streaming i/o for afp_read.

this is all from the perspective of the client. it basically does the reverse of dsi_write. on first entry, it will send off the header plus whatever is in its command buffer. it returns the amount of stuff still to be read (constrained by the buffer size).

◆ dsi_setstatus()

void dsi_setstatus ( DSI * ,
char * ,
const size_t  )
extern

◆ dsi_stream_read()

size_t dsi_stream_read ( DSI * dsi,
void * data,
const size_t length )
extern

Read data from DSI buffer.

Essentially a loop around buf_read() to ensure "length" bytes are read from dsi->buffer and/or the socket.

Returns
length on success, some value smaller than length indicates an error

◆ dsi_stream_read_file()

ssize_t dsi_stream_read_file ( DSI * dsi,
int fromfd,
off_t off,
const size_t len,
const int err )
extern

◆ dsi_stream_receive()

int dsi_stream_receive ( DSI * dsi)
extern

Read DSI command and data.

Parameters
dsi(rw) DSI handle
Returns
DSI function on success, 0 on failure

◆ dsi_stream_send()

int dsi_stream_send ( DSI * dsi,
void * buf,
size_t length )
extern

write data.

Returns
0 on failure.
Note
this assumes that dsi_len will never cause an overflow in the data buffer.

◆ dsi_stream_write()

ssize_t dsi_stream_write ( DSI * dsi,
void * data,
const size_t length,
int mode )
extern

write raw DSI data

Checks against EINTR aren't necessary if all of the signals have SA_RESTART specified.

Returns
actual bytes written, -1 on error

◆ dsi_tcp_init()

int dsi_tcp_init ( DSI * dsi,
const char * hostname,
const char * inaddress,
const char * inport )
extern

Initialize DSI over TCP.

Parameters
[in,out]dsiDSI handle
[in]hostnamepointer to hostname string
[in]inaddressOptional IPv4 or IPv6 address with an optional port, may be NULL
[in]inportpointer to port string

Creates listening AFP/DSI socket. If the parameter inaddress is NULL, then we listen on the wildcard address, i,e, on all interfaces. That should mean listening on the IPv6 address "::" on IPv4/IPv6 dual stack kernels, accepting both v4 and v6 requests.

If the parameter inaddress is not NULL, then we only listen on the given address. The parameter may contain a port number using the URL format for address and port:

IPv4, IPv4:port, IPv6, [IPv6], [IPv6]:port

Parameter inport must be a valid pointer to a port string and is used if the inaddress parameter doesn't contain a port.

Returns
0 on success, -1 on failure

◆ dsi_tickle()

int dsi_tickle ( DSI * dsi)
extern

server generated tickles. as this is only called by the tickle handler, we don't need to block signals.

◆ dsi_write()

size_t dsi_write ( DSI * dsi,
void * buf,
const size_t buflen )
extern

fill up buf and then return. this should be called repeatedly until all the data has been read. i block alarm processing during the transfer to avoid sending unnecessary tickles.

◆ dsi_writeflush()

void dsi_writeflush ( DSI * dsi)
extern

flush any unread buffers.

◆ dsi_writeinit()

size_t dsi_writeinit ( DSI * dsi,
void * buf,
const size_t buflen )
extern