/* * cutlass.h * * Structure and function declarations for cutlass. * * Copyright (c) 2004 Todd MacDermid * */ #ifndef CUTLASS_H #define CUTLASS_H #ifndef HAVE_INET_NTOP #define INET_ADDRSTRLEN 16 #endif /********************************************************************* * Header file include section ********************************************************************/ #include #include #include #include #include #include /********************************************************************* * Constant definitions ********************************************************************/ #define CUTLASS_NAME_LEN 128 /* Max channel or user name len */ #define CUTLASS_FILENAME_LEN 256 /* Max namelen for files */ #define CUTLASS_DIRECTORY_LEN 256 /* Max len of directory names */ #define CUTLASS_DEFAULT_DIRENT 256 /* Default max # of returned entries */ #define CUT_ID_LEN 32 /* Length of connection or group ID */ #define CUT_SESSION_KEY_MAX 64 /* Max session key size */ #define CUT_CSUM_LEN 32 /* Size of hashes for file xfer */ #define CUT_FILE_TRANSIT_MAX 10 /* Max number simultaneous files in * transit over one connection */ #define CUT_MSG_LEN_MAX 65000 #define CUT_DIR_MSG_MAX 128000 /* Max length of directory reply */ #define CUT_DEFAULT_PORT 8365 /* It's a number, innit? */ #define CUT_MAX_CONN 1024 /* Max number of open connections */ #define CUT_MAX_GAPS 100 /* Max # of gaps in files or msgs */ #define CUT_HK_ARRAY_SZ 2048 /* Number of conn slots in array */ #define CUT_NUM_CHANNELS 255 /* Number of possible channel ids */ #define CUT_RATE_INIT 2 /* Default # of pps transmitted */ #define CUT_ADDR_MAX 16 /* Max length of address supported */ #define CUT_IPV4 1 /* Address type */ #define CUT_IPV6 2 /* Address type */ /* Default MTU: IPv4 minimum reassembly size (576) - UDP header (8) - IP header (40) - Cutlass stuff (20+16) Note that the IPv4 minimum MTU is actually 68 bytes, but all IPv4 implementations must be able to process packets up to 576 bytes (possibly fragmented). This value for IPv6 would be (1500-40-8-20-16). */ #define CUT_DEFAULT_MTU 500 #define CUT_TIMEOUT_INTERVAL 600 /* Seconds of inactivity after * which sessions are removed */ #define CUT_PING_INTERVAL 30 /* Number of quiet seconds to wait * before pinging */ #define CUT_SHUTDOWN_GRACE 10 /* How long to attempt to shut * connections down */ #define CUT_PING_RETRANSMIT_INTERVAL 3 /* How many seconds between pings * on an inactive channel */ #define CUT_CLOSE_RETRANSMIT_INTERVAL 3 /* How many seconds between pings * on an inactive channel */ #define CUT_KEX_RETRANSMIT_INTERVAL 3 /* How long to wait between un-ACKed * KEX retransmits */ #define CUT_INIT_RETRANSMIT_INTERVAL 3 /* How long to wait between init * retransmits */ #define CUT_FILE_ACK_INTERVAL 1 /* How long to wait between ACK * retransmits */ #define CUT_IN 0 /* Direction for internal logic */ #define CUT_OUT 1 /* Direction for internal logic */ #define CUT_NANOSEC 1000000000 /* * A cutlass_capabilities structure exists for each remote connection, * and defines what the remote connection is capable of performing. */ typedef uint32_t cutlass_capability_t; #define CAN_RECV_MSGS 0x00000001 #define CAN_RECV_FILES 0x00000002 #define CAN_RECV_AUDIO 0x00000004 #define CAN_RECV_VIDEO 0x00000008 #define CAN_FORWARD 0x00000010 #define CAN_SERVE_DIR 0x00000020 #define CAN_SERVE_FILES 0x00000040 /******************************************************************** * Cutlass header files that include data structure definitions ********************************************************************/ #include #include #include #include #include #include /********************************************************************* * Packet header definitions ********************************************************************/ /* * The Cutlass packet header. This is at the beginning of every cutlass * packet. */ struct cutlass_packet_hdr { uint8_t cut_type; uint8_t channel_id; uint16_t length; /* Length of _payload_ not full packet */ }; #define CUT_HDR_LEN 4 /* * Cutlass packet type (cut_type) definitions */ #define CUT_PING 1 /* Keepalive request */ #define CUT_PONG 2 /* Keepalive reply */ #define CUT_FORWARD_REQ 3 /* Request to forward */ #define CUT_FILE_GET 4 /* File request packet */ #define CUT_TRANS_INIT 5 /* Channel transport initialization */ #define CUT_TRANS_INIT_ACK 6 /* Ack receipt of CUT_TRANS_INIT */ #define CUT_TRANS_SEND 7 /* Channel transport sending */ #define CUT_TRANS_ACK 8 /* Channel transport acknowledgement */ #define CUT_TRANS_COMPLETE 9 /* Completion of channel transport */ #define CUT_INFO_REQ 10 /* Request for information */ #define CUT_CONN_INFO 11 /* Inform about what we can do */ #define CUT_KEX_CHELLO 12 /* Key exchange initiation packet */ #define CUT_KEX_SHELLO 13 /* Key exchange reply packet */ #define CUT_KEX_CDHG 14 /* Key exchange finalization packet */ #define CUT_KEX_SDHG 15 /* Key exchange finalization packet */ #define CUT_KEX_DONE 16 /* Key exchange finalization packet */ #define CUT_CHANNEL_CLOSE 17 /* Indicate closure of channel */ #define CUT_AUDIO_INFO 18 /* Audio information packets */ #define CUT_AUDIO_DATA 19 /* Audio data packets */ #define CUT_AUDIO_REQ 20 /* Audio connection requests */ #define CUT_GRP_ADMIN 21 /* Group functionality packets */ #define CUT_END 254 /* Terminate connection init */ #define CUT_END_ACK 255 /* Terminate connection end */ /* * The cutlass ping header. This is the payload on packets of type * CUT_PING */ struct cutlass_ping_hdr { uint64_t time_sec; uint32_t time_nsec; }; #define CUT_PING_HDR_LEN 12 /* * The cutlass pong header. This is the payload on packets of type * CUT_PONG */ struct cutlass_pong_hdr { uint64_t time_sec; uint32_t time_nsec; }; #define CUT_PONG_HDR_LEN 12 /* * The cutlass file transfer initiation packet is used to either offer * a file for transfer, or to respond to a file request packet header */ struct cutlass_file_init_hdr { uint8_t file_csum[CUT_CSUM_LEN]; uint16_t file_name_len; uint8_t file_name[CUTLASS_FILENAME_LEN]; }; #define FILE_INIT_HDR_LEN CUT_CSUM_LEN + 2 /* * The Cutlass file transfer packet header. This comes after the cutlass * packet header on packets of type CUT_FILE_SEND */ struct cutlass_file_send_hdr { uint32_t offset; }; #define CUT_FILE_SEND_HDR_LEN 4 /* * The cutlass file acknowledgement packet informs the remote side * of what we've seen, and what we have yet to receive. */ struct cutlass_file_ack_hdr { uint16_t num_gaps; }; #define CUT_FILE_ACK_HDR_LEN 2 struct cutlass_msg_init_hdr { uint8_t msg_dest_type; uint8_t destination[CUT_ID_LEN]; }; #define MSG_INIT_HDR_LEN 1 + CUT_ID_LEN /* * The cutlass connection info header contains information about our * connection, including what capabilities we offer, and our preferred * nickname */ struct cutlass_conn_info { cutlass_capability_t capabilities; uint8_t name_len; uint8_t name[CUTLASS_NAME_LEN]; }; /* * The cutlass group_admin header contains all the juicy goodness needed * to administer, join, and leave groups. */ #define GROUP_CODE_ACK 0 /* Acknowledge receipt of group command */ #define GROUP_CODE_INVITE 1 /* Invite a connection to your group */ #define GROUP_CODE_KICK 2 /* Inform a user they've been kicked */ #define GROUP_CODE_JOIN 3 /* Tell server of your wish to join */ #define GROUP_CODE_DROP 4 /* Tell server you wish to not join */ /* (Also used to drop from group */ #define GROUP_CODE_LIST_REQ 5 /* Request a list of users in the group */ #define GROUP_CODE_LIST 6 /* Provide a list of group users */ /* The following are currently unused, we'll just do a LIST for each change */ #define GROUP_CODE_ADD 7 /* Server tells group users to add conn */ #define GROUP_CODE_REMOVE 8 /* Server tells members to remove conn */ struct cutlass_group_hdr { uint8_t code; uint16_t sequence; uint8_t group_id[CUT_ID_LEN]; }; #define CUT_GRP_HDR_LEN 3 + CUT_GRPID_LEN /***************************************************************** * Internal structure definitions ****************************************************************/ /* * struct gaplist stores the list of gaps yet to be filled in for a * file or message in transit. * * Gaplist ought to be a sorted structure of some sort. Binary tree, * perhaps? And should we have a maximum number of allowable gaps, to * prevent memory starvation? * * For right now, gaplists are simple doubly-linked lists. Will be sorted * soon, but be sure to only poke at them via official functions in * gaps.c */ struct gapnode { uint32_t gap_start; uint32_t gap_end; struct gapnode *next_gap; struct gapnode *prev_gap; }; struct gaplist { int num_gaps; struct gapnode *gap_head; struct gapnode *gap_tail; }; /******************************************************************* * struct channel details information about the status of a current * channel, be it message, directory, or file transfer *******************************************************************/ /* channel_type definitions */ #define CHANNEL_NONE 0 #define CHANNEL_MSG 1 #define CHANNEL_FILE 2 #define CHANNEL_GROUP 3 #define CHANNEL_REQUEST 4 #define CHANNEL_DIR_INFO 5 #define CHANNEL_REPLY 6 /* channel_state definitions */ #define CUT_CHANNEL_STATE_INIT 0 #define CUT_CHANNEL_STATE_WAITING 1 #define CUT_CHANNEL_STATE_TRANSFERRING 2 #define CUT_CHANNEL_STATE_FINISH 3 /* * file_transit_info.end definitions (determines if we're writing from * the front or the back of the block. */ #define CUT_FRONT_END 0 #define CUT_BACK_END 1 struct channel { int reset_loc; int channel_state; int end; uint8_t channel_type; uint8_t channel_id; uint32_t cur_offset; uint32_t data_size; uint32_t request_id; struct timespec last_received; struct timespec last_sent; struct gaplist *gap_list; void *channel_info; void * user_obj; uint8_t *buffer; }; /* * struct msg_transit_info stores information about each * message we have not yet fully received or sent. */ struct msg_transit_info { uint8_t msg_dest_type; uint8_t destination[CUT_ID_LEN]; }; /* * struct file_transit_info stores information about each fragmented * file we have not yet fully received or sent. */ struct file_transit_info { uint8_t file_csum[CUT_CSUM_LEN]; char name[CUTLASS_FILENAME_LEN]; int fd; }; /* * struct directory_info */ /* * The cutlass_permissions structure is used primarily for file transfer * operations, detailing whether people can browse or push files, and * what level of authentication is needed. */ struct cutlass_permissions { char browse_dir[CUTLASS_DIRECTORY_LEN]; char save_dir[CUTLASS_DIRECTORY_LEN]; int permit_browse; int permit_push; int permit_audio; }; #define NOT_ALLOWED 0 #define USER_ALLOW_CHECK 1 #define ALL_ALLOWED 2 /* * Ah, struct cutlass_connection. The mega-monster structure containing * info about each connection we have with others. This should, * theoretically, give us easy lookups to info we need whenever we * receive a packet. */ struct cutlass_connection { int socket; struct sockaddr_in remote_addr; struct cutlass_connection *relay; int conn_state; int rate; struct channel in_channels[CUT_NUM_CHANNELS]; struct channel out_channels[CUT_NUM_CHANNELS]; int last_out_channel; uint8_t path_flags; uint8_t conn_name[CUTLASS_NAME_LEN]; uint16_t mtu; int have_info; cutlass_public_key peer_key; /* the public key of our peer */ uint8_t fingerprint[CUT_ID_LEN]; /* SHA-1 fingerprint of key */ cutlass_keyset keyset; /* the cryptovariables for this session */ void* kex_info; /* storage for kex info, cause we're non-blocking */ struct timespec last_packet_sent; struct timespec last_packet_received; struct timespec last_ping_sent; cutlass_capability_t capabilities; socklen_t remote_addr_size; struct file_transit_info *transiting_files_in; int file_transit_num_in; struct file_transit_info *transiting_files_out; int file_transit_num_out; struct msg_transit_info *transiting_msgs_in; int msg_transit_num_in; struct msg_transit_info *transiting_msgs_out; int msg_transit_num_out; htab *requests; uint32_t last_request; pthread_mutex_t conn_mutex; cutlass_conn_audio_t *conn_audio_handle; int audio_state; }; typedef struct cutlass_connection conn_t; /* * cutlass_connection state (conn_state) definitions. These need additional * attention from Jack, we need to break it down by packet flow. */ #define CUTSTATE_DELETING 0 #define CUTSTATE_UNINITIALZED 1 #define CUTSTATE_C_SENT_HELLO 2 #define CUTSTATE_S_SENT_HELLO 3 #define CUTSTATE_C_SENT_DH 4 #define CUTSTATE_S_SENT_DH 5 #define CUTSTATE_BACKCONNECT_SENT 6 #define CUTSTATE_ACTIVE 7 #define CUTSTATE_CLOSE_SENT 8 #define CUTSTATE_CLOSE_ACKED 9 /* * cutlass_connection path_flags definitions. These flags state what types * of routes to/from the remote host are available to us. */ #define CUTROUTE_SOCKET 0x01 #define CUTROUTE_SOCKADDR 0x02 #define CUTROUTE_RELAYED 0x04 /* * The conn_delete stack is a way for the housekeeping thread to ensure * that none of it's saved connection pointers "just disappear" from * underneath it. The connection deleting function will push these * objects onto the stack, and the housekeeping thread will actually * free the connection memory when it is ready for processing. */ struct conn_delete_stack { struct conn_delete_stack *next; struct cutlass_connection *conn; }; /* Below are valid action handler types */ #define CUT_NOACTION 0 #define CUT_USER_CONN_REQ 1 #define CUT_USER_CONN 2 #define CUT_USER_DROP 3 #define CUT_USER_TIMEOUT 4 #define CUT_GRP_JOIN 5 #define CUT_GRP_JOIN_REQ 6 #define CUT_GRP_INVITE 7 #define CUT_GRP_LEAVE 8 #define CUT_MSG_RECV 9 #define CUT_FILE_OFFER 10 #define CUT_FILE_REQ 11 #define CUT_FILE_ACCEPT 12 #define CUT_FILE_REJECT 13 #define CUT_FILE_ABORT 14 #define CUT_FILE_SEND_DONE 15 #define CUT_FILE_RECV_DONE 16 #define CUT_SND_OFFER 17 #define CUT_SND_ACCEPT 18 #define CUT_SND_REJECT 19 #define CUT_SND_DONE 20 #define CUT_SYS_MSG 21 #define CUT_ACTION_MAX 22 /* * Struct cut_action_obj pointers are passed in as arguments to cutlass * action handlers. They contain all the info needed for any kind of * action. Should be opaque to the user. */ struct cut_action_obj { void *cut_handle; uint8_t conn_fingerprint[CUT_ID_LEN]; int action_type; /* CUT_USER_DROP, etc */ char remote_nick[CUTLASS_NAME_LEN]; struct sockaddr_in remote_addr; char group_nick[CUTLASS_NAME_LEN]; cutlass_public_key remote_key; cutlass_public_key group_key; char file_name[CUTLASS_FILENAME_LEN]; uint8_t file_csum[CUT_CSUM_LEN]; int external_channel_id; uint32_t file_size; char msg[CUT_MSG_LEN_MAX]; void *data; }; /* * struct transport_poll_obj objects are pointers that are passed back * in the case of a cutlass_transport_poll() call being made that * contain stats about the current transfer */ struct transport_poll_obj { int total_bytes; int sent_bytes; uint8_t channel_type; uint8_t channel_state; void *user_obj; }; typedef struct transport_poll_obj poll_t; /* cutlass_handle->verbose options */ #define CUT_QUIET 0 #define CUT_ERROR 1 #define CUT_INFO 2 #define CUT_DEBUG 3 #define CUT_SUPAA_DEBUG 4 /* * The cutlass_handle structure is the overarching structure that * points to the information needed by all components in the program. * There can be only one, and it gets passed around the various functions. * This structure also contains stacks for the threads to pass messages to * each other. */ struct cutlass_handle { cutlass_private_key local_key; void *action_handlers[CUT_ACTION_MAX]; fd_set err_sockets; fd_set read_sockets; fd_set saved_sockets; htab *connections; htab *directory; htab *groups; int listen_socket; int max_fd; int running_state; /* 1 for running, 0 for shutting down */ int verbose; int action_lock; int print_timestamp; pthread_mutex_t group_mutex; pthread_mutex_t directory_mutex; pthread_mutex_t action_mutex; pthread_mutex_t handle_mutex; pthread_mutex_t htab_mutex; pthread_mutex_t del_stack_mutex; pthread_mutex_t fd_set_mutex; pthread_t listen_tid; pthread_t housekeeping_tid; struct conn_delete_stack *del_stack; struct cutlass_conn_info local_info; struct cutlass_permissions perms; uint8_t id[CUT_ID_LEN]; struct timespec sleep_time; cutlass_options* user_opts; /** AUDIO SCHMUTZIG **/ int audio_driver_type; pthread_t audio_read_tid; pthread_t audio_write_tid; pthread_mutex_t audio_mutex; /* lock for audio capture handle */ int audio_refcnt; /* reference count for capture handle */ cutlass_audio_t *audio_handle; /* capture handle */ }; typedef struct cutlass_handle cutlass_t; /******************************************************************** * The action handler function definition ********************************************************************/ typedef int (*cut_action_handler)(cutlass_t *cut_handle, struct cut_action_obj *action_object); struct action_combo { cutlass_t *cut_handle; struct cut_action_obj *action_obj; cut_action_handler action_handler; }; /****************************************************************** * Group structures definition *****************************************************************/ struct member_node { struct member_node *next; uint8_t member_id[CUT_ID_LEN]; int admin; }; struct cutlass_group { int admin; struct member_node *members; uint8_t group_id[CUT_ID_LEN]; uint8_t group_name[CUTLASS_NAME_LEN]; uint16_t sequence; cutlass_public_key public_key; cutlass_private_key private_key; pthread_mutex_t group_mutex; }; typedef struct cutlass_group group_t; /******************************************************************** * All cutlass include files, so that our code can simply * #include , and we don't have to worry about * sub-including what was getting to be a rather lengthy list. *******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /* CUTLASS_H */