/* * uhub - A tiny ADC p2p connection hub * Copyright (C) 2007-2009, Jan Vidar Krey * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef HAVE_UHUB_USER_H #define HAVE_UHUB_USER_H struct hub_info; struct hub_iobuf; enum user_state { state_protocol = 0, /**<< "User must send a valid protocol handshake" */ state_identify = 1, /**<< "User must send identification message (INF) " */ state_verify = 2, /**<< "User must send password to verify identification" */ state_normal = 3, /**<< "User is logged in." */ state_cleanup = 4, /**<< "User is disconnected, but other users need to be notified." */ state_disconnected = 5, /**<< "User is disconnected" */ }; enum user_flags { feature_base = 0x00000001, /** BASE: Basic configuration (required by all clients) */ feature_auto = 0x00000002, /** AUT0: Automatic nat detection traversal */ feature_bbs = 0x00000004, /** BBS0: Bulletin board system (not supported) */ feature_ucmd = 0x00000008, /** UCMD: User commands (not supported by this software) */ feature_zlif = 0x00000010, /** ZLIF: gzip stream compression (not supported) */ feature_tiger = 0x00000020, /** TIGR: Client supports the tiger hash algorithm */ feature_bloom = 0x00000040, /** BLO0: Bloom filter (not supported) */ feature_ping = 0x00000080, /** PING: Hub pinger information extension */ feature_link = 0x00000100, /** LINK: Hub link (not supported) */ flag_ignore = 0x01000000, /** Ignore further reads */ flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */ flag_choke = 0x04000000, /** Choked: Cannot send, waiting for write event */ flag_want_read = 0x08000000, /** Need to read (SSL) */ flag_want_write = 0x10000000, /** Need to write (SSL) */ flag_user_list = 0x20000000, /** Send queue bypass (when receiving the send queue) */ flag_pipeline = 0x40000000, /** Hub message pipelining */ flag_nat = 0x80000000, /** nat override enabled */ }; enum user_quit_reason { quit_unknown = 0, quit_disconnected = 1, /** User disconnected */ quit_kicked = 2, /** User was kicked */ quit_banned = 3, /** User was banned */ quit_timeout = 4, /** User timed out (no data for a while) */ quit_send_queue = 5, /** User's send queue was overflowed */ quit_memory_error = 6, /** Not enough memory available */ quit_socket_error = 7, /** A socket error occured */ quit_protocol_error = 8, /** Fatal protocol error */ quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */ quit_hub_disabled = 10, /** Hub is disabled. No new connections allowed */ quit_ghost_timeout = 11, /** The user is a ghost, and trying to login from another connection */ }; struct hub_user_info { sid_t sid; /** session ID */ char cid[MAX_CID_LEN+1]; /** global client ID */ char nick[MAX_NICK_LEN+1]; /** User's nick name */ }; /** * This struct contains additional information about the user, such * as the number of bytes and files shared, and the number of hubs the * user is connected to, etc. */ struct hub_user_limits { uint64_t shared_size; /** Shared size in bytes */ size_t shared_files; /** The number of shared files */ size_t upload_slots; /** The number of upload slots */ size_t hub_count_user; /** The number of hubs connected as user */ size_t hub_count_registered; /** The number of hubs connected as registered user */ size_t hub_count_operator; /** The number of hubs connected as operator */ size_t hub_count_total; /** The number of hubs connected to in total */ }; struct hub_user_net_io { int sd; /** socket descriptor */ struct event event; /** libevent struct for read/write events */ struct event timeout; /** timeout handling */ struct hub_recvq* recv_queue; struct hub_sendq* send_queue; time_t tm_connected; /** time when user connected */ time_t tm_last_read; /** time the user last received something from the hub */ time_t tm_last_write; /** time the user last sent something to the hub */ struct ip_addr_encap ipaddr; /** IP address of connected user */ #ifdef SSL_SUPPORT SSL* ssl; /** SSL handle */ #endif /* SSL_SUPPORT */ }; struct hub_user { struct hub_user_net_io net; /** Network information data */ enum user_state state; /** see enum user_state */ enum user_credentials credentials; /** see enum user_credentials */ struct hub_user_info id; /** Contains nick name and CID */ int flags; /** see enum user_features */ char user_agent[MAX_UA_LEN+1];/** User agent string */ struct linked_list* feature_cast; /** Features supported by feature cast */ struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */ struct hub_info* hub; /** The hub instance this user belong to */ struct hub_user_limits limits; /** Data used for limitation */ int quit_reason; /** Quit reason (see user_quit_reason) */ }; /** * Create a user with the given socket descriptor. * This basically only allocates memory and initializes all variables * to an initial state. * * state is set to state_protocol. * * @param sd socket descriptor associated with the user * @return User object or NULL if not enough memory is available. */ extern struct hub_user* user_create(struct hub_info* hub, int sd); /** * Delete a user. * * !WRONG! If the user is logged in a quit message is issued. */ extern void user_destroy(struct hub_user* user); /** * Disconnect a user. * This will mark the user connection ready for being terminated. * A reason can be given using the enum user_quit_reason. * * Things to be done when calling this: * - Mark the user with state_cleanup * * If the user is logged in to the hub: * - post message: UHUB_EVENT_USER_QUIT * * @param user User to disconnect * @param reason See enum user_quit_reason */ extern void user_disconnect(struct hub_user* user, int reason); /** * This associates a INF message to the user. * If the user already has a INF message associated, then this is * released before setting the new one. * * @param info new inf message (can be NULL) */ extern void user_set_info(struct hub_user* user, struct adc_message* info); /** * Update a user's INF message. * Will parse replace all ellements in the user's inf message with * the parameters from the cmd (merge operation). */ extern void user_update_info(struct hub_user* user, struct adc_message* cmd); /** * Specify a user's state. * NOTE: DON'T, unless you know what you are doing. */ extern void user_set_state(struct hub_user* user, enum user_state); /** * Returns 1 if the user is in state state_normal, or 0 otherwise. */ extern int user_is_logged_in(struct hub_user* user); /** * Returns 1 if the user is in state_protocol. * Returns 0 otherwise. */ extern int user_is_protocol_negotiating(struct hub_user* user); /** * Returns 1 if the user is in state_protocol, state_identify or state_verify. * Returns 0 otherwise. */ extern int user_is_connecting(struct hub_user* user); /** * Returns 1 only if the user is in state_cleanup or state_disconnected. */ extern int user_is_disconnecting(struct hub_user* user); /** * Returns 1 if a user is protected, which includes users * having any form of elevated privileges. */ extern int user_is_protected(struct hub_user* user); /** * Returns 1 if a user is registered, with or without privileges. */ extern int user_is_registered(struct hub_user* user); /** * User supports the protocol extension as given in fourcc. * This is usually set while the user is connecting, but can * also be used to subscribe to a new class of messages from the * hub. * * @see enum user_flags */ extern void user_support_add(struct hub_user* user, int fourcc); /** * User no longer supports the protocol extension as given in fourcc. * This can be used to unsubscribe to certain messages generated by * the hub. * @see enum user_flags */ extern void user_support_remove(struct hub_user* user, int fourcc); /** * Sets the nat override flag for a user, this allows users on the same * subnet as a natted hub to spoof their IP in order to use active mode * on a natted hub. */ extern void user_set_nat_override(struct hub_user* user); extern int user_is_nat_override(struct hub_user* user); /** * Set a flag. @see enum user_flags */ extern void user_flag_set(struct hub_user* user, enum user_flags flag); extern void user_flag_unset(struct hub_user* user, enum user_flags flag); /** * Get a flag. @see enum user_flags */ extern int user_flag_get(struct hub_user* user, enum user_flags flag); /** * Check if a user supports 'feature' for feature casting (basis for 'Fxxx' messages) * The feature cast is specified as the 'SU' argument to the user's * INF-message. * * @param feature a feature to lookup (example: 'TCP4' or 'UDP4') * @return 1 if 'feature' supported, or 0 otherwise */ extern int user_have_feature_cast_support(struct hub_user* user, char feature[4]); /** * Set feature cast support for feature. * * @param feature a feature to lookup (example: 'TCP4' or 'UDP4') * @return 1 if 'feature' supported, or 0 otherwise */ extern int user_set_feature_cast_support(struct hub_user* u, char feature[4]); /** * Remove all feature cast support features. */ extern void user_clear_feature_cast_support(struct hub_user* u); /** * Mark the user with a want-write flag, meaning it should poll for writability. */ extern void user_net_io_want_write(struct hub_user* user); /** * Mark the user with a want read flag, meaning it should poll for readability. */ extern void user_net_io_want_read(struct hub_user* user); /** * Set timeout for connetion. * @param seconds the number of seconds into the future. */ extern void user_set_timeout(struct hub_user* user, int seconds); /** * Reset the last-write timer. */ extern void user_reset_last_write(struct hub_user* user); /** * Reset the last-write timer. */ extern void user_reset_last_read(struct hub_user* user); #endif /* HAVE_UHUB_USER_H */