/* * uhub - A tiny ADC p2p connection hub * Copyright (C) 2007-2010, 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) */ feature_adcs = 0x00000200, /** ADCS: ADC over TLS/SSL */ flag_muted = 0x00800000, /** User is muted (cannot chat) */ 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_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */ quit_hub_disabled = 11, /** Hub is disabled. No new connections allowed */ quit_ghost_timeout = 12, /** The user is a ghost, and trying to login from another connection */ }; /** Returns an apropriate string for the given quit reason */ extern const char* user_get_quit_reason_string(enum user_quit_reason); 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 */ struct ip_addr_encap addr; /** User's IP address */ }; /** * 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 { 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 */ uint32_t 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_recvq* recv_queue; struct hub_sendq* send_queue; struct net_connection* connection; /** Connection data */ struct hub_user_limits limits; /** Data used for limitation */ enum user_quit_reason 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, struct net_connection* con, struct ip_addr_encap* addr); /** * Delete a user. * * !WRONG! If the user is logged in a quit message is issued. */ extern void user_destroy(struct hub_user* user); /** * 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); extern const char* user_get_address(struct hub_user* user); /** * 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); #endif /* HAVE_UHUB_USER_H */