Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

nodes.h

Go to the documentation of this file.
00001 /*
00002  * $Id: nodes.h,v 1.40 2005/12/16 14:51:42 cbiere Exp $
00003  *
00004  * Copyright (c) 2001-2003, Raphael Manfredi
00005  *
00006  *----------------------------------------------------------------------
00007  * This file is part of gtk-gnutella.
00008  *
00009  *  gtk-gnutella is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  gtk-gnutella is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with gtk-gnutella; if not, write to the Free Software
00021  *  Foundation, Inc.:
00022  *      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *----------------------------------------------------------------------
00024  */
00025 
00026 #ifndef _core_nodes_h_
00027 #define _core_nodes_h_
00028 
00029 #include "common.h"
00030 
00031 #include "mq.h"
00032 #include "sq.h"
00033 #include "rx.h"
00034 #include "qrp.h"
00035 #include "hsep.h"
00036 #include "gnutella.h"
00037 #include "extensions.h"
00038 
00039 #include "if/core/wrap.h"           /* For wrap_io_t */
00040 #include "if/core/hsep.h"
00041 #include "if/core/guid.h"
00042 #include "if/core/hcache.h"
00043 #include "if/core/nodes.h"
00044 
00045 #include "lib/header.h"
00046 
00047 typedef enum node_protocol_types {
00048     PROTOCOL_TYPE_GNUTELLA = 0,
00049     PROTOCOL_TYPE_G2
00050 } node_protocol_types_t;
00051 
00052 typedef enum {
00053     NODE_MAGIC = 0x67f8e02f
00054 } node_magic_t;
00055 
00067 #define NODE_RX_FC_HALF_PERIOD  300     
00069 struct node_rxfc_mon {
00070     time_t start_half_period;   
00071     time_t fc_last_half;        
00072     time_t fc_accumulator;      
00073     time_t fc_start;            
00074 };
00075 
00088 #define MAX_CACHE_HOPS  6       /* We won't handle anything larger */
00089 
00090 #define CACHE_HOP_IDX(h)    (((h) > MAX_CACHE_HOPS) ? MAX_CACHE_HOPS : (h))
00091 
00092 /*
00093  * Throttle periods for ping reception, depending on the peer mode.
00094  * This is applicable for regular pings, not alive pings.
00095  */
00096 #define PING_REG_THROTTLE       3       
00097 #define PING_LEAF_THROTTLE      60      
00099 typedef struct gnutella_node {
00100     node_magic_t magic;         
00101     gnet_node_t node_handle;    
00102     node_peer_t peermode;       
00103     node_peer_t start_peermode; 
00105     gchar error_str[256];       
00106     struct gnutella_socket *socket;     
00107     guint8 proto_major;         
00108     guint8 proto_minor;         
00109     node_protocol_types_t protocol_type;
00110 
00111     guint8 qrp_major;           
00112     guint8 qrp_minor;           
00113     guint8 uqrp_major;          
00114     guint8 uqrp_minor;          
00115     gchar *vendor;              
00116     gint country;               
00117     union vendor_code vcode;    
00118     gpointer io_opaque;         
00120     struct gnutella_header header;  
00121     extvec_t extvec[MAX_EXTVEC];    
00122     gint extcount;                  
00124     guint32 size; 
00126     gchar *data;                
00127     guint32 pos;                
00129     gnet_node_state_t status;   
00130     guint32 flags;              
00131     guint32 attrs;              
00133     guint8 hops_flow;           
00134     guint8 max_ttl;             
00135     guint16 degree;             
00137     GHashTable *qseen;          
00138     GHashTable *qrelayed;       
00139     GHashTable *qrelayed_old;   
00140     time_t qrelayed_created;    
00142     guint32 sent;               
00143     guint32 received;           
00144     guint32 tx_dropped;         
00145     guint32 rx_dropped;         
00146     guint32 n_bad;              
00147     guint16 n_dups;             
00148     guint16 n_hard_ttl;         
00149     guint32 n_weird;            
00150     guint32 n_hostile;          
00152     guint32 allocated;          
00153     gboolean have_header;       
00155     time_t last_update;         
00156     time_t last_tx;             
00157     time_t last_rx;             
00158     time_t connect_date;        
00159     time_t tx_flowc_date;       
00160     struct node_rxfc_mon *rxfc; 
00161     time_t shutdown_date;       
00162     time_t up_date;             
00163     time_t leaf_flowc_start;    
00164     guint32 shutdown_delay;     
00166     const gchar *remove_msg;    
00168     host_addr_t addr;           
00169     guint16 port;               
00171     gchar *guid;                
00172     host_addr_t proxy_addr;     
00173     guint16 proxy_port;         
00175     mqueue_t *outq;             
00176     squeue_t *searchq;          
00177     rxdrv_t *rx;                
00179     gpointer routing_data;      
00180     gpointer sent_query_table;  
00181     gpointer recv_query_table;  
00182     gpointer qrt_update;        
00183     gpointer qrt_receive;       
00184     qrt_info_t *qrt_info;       
00186     gpointer alive_pings;       
00187     time_t last_alive_ping;     
00188     guint alive_period;         
00190     wrap_buf_t hello;           
00192     /*
00193      * Round-trip time (RTT) measurements operated via Time Sync
00194      * (more accuracy than with traditional ping / pong exchanges).
00195      * Figures are in ms.
00196      */
00197 
00198     guint32 tcp_rtt;            
00199     guint32 udp_rtt;            
00200     gpointer tsync_ev;          
00202     /*
00203      * Data structures used by the ping/pong reduction scheme.
00204      *      --RAM, 02/02/2002
00205      */
00206 
00207     guint32 id;                 
00208     guint ping_throttle;        
00209     time_t ping_accept;         
00210     time_t next_ping;           
00211     gchar ping_guid[GUID_RAW_SIZE]; 
00212     guchar pong_needed[MAX_CACHE_HOPS+1];   
00213     guchar pong_missing;    
00215     host_addr_t gnet_addr;      
00216     guint16 gnet_port;          
00217     guint32 gnet_files_count;   
00218     guint32 gnet_kbytes_count;  
00219     host_addr_t gnet_pong_addr; 
00220     host_addr_t gnet_qhit_addr; 
00221     gchar *gnet_guid;           
00223     guint32 n_ping_throttle;  
00224     guint32 n_ping_accepted;  
00225     guint32 n_ping_special;   
00226     guint32 n_ping_sent;      
00227     guint32 n_pong_received;  
00228     guint32 n_pong_sent;      
00230     /*
00231      * Traffic statistics -- RAM, 13/05/2002.
00232      */
00233 
00234     gint32 tx_given;            
00235     gint32 tx_deflated;         
00236     gint32 tx_written;          
00238     gint32 rx_given;            
00239     gint32 rx_inflated;         
00240     gint32 rx_read;             
00242     /*
00243      * Various Gnutella statistics -- RAM, 10/12/2003.
00244      *
00245      * qrp_queries/qrp_matches is used by both leaf and ultra nodes:
00246      * . Leaf structures use it to count the amount of queries received versus
00247      *   queries sent after QRP filtering by the ultra node (us).
00248      * . Ultra structures use it to count the amount of queries received from
00249      *   the ultra node by the leaf node (us) versus the amount of queries
00250      *   that really caused a match to one of our files.
00251      */
00252 
00253     guint32 qrp_queries;        
00254     guint32 qrp_matches;        
00255     guint32 rx_queries;         
00256     guint32 tx_queries;         
00257     guint32 rx_qhits;           
00258     guint32 tx_qhits;           
00260     hsep_ctx_t *hsep;   
00262 } gnutella_node_t;
00263 
00264 /*
00265  * Node flags.
00266  */
00267 
00268 #define NODE_F_HDSK_PING    0x00000001 
00269 #define NODE_F_STALE_QRP    0x00000002 
00270 #define NODE_F_INCOMING     0x00000004 
00271 #define NODE_F_ESTABLISHED  0x00000008 
00272 #define NODE_F_VALID        0x00000010 
00273 #define NODE_F_ALIEN_IP     0x00000020 
00274 #define NODE_F_WRITABLE     0x00000040 
00275 #define NODE_F_READABLE     0x00000080 
00276 #define NODE_F_BYE_SENT     0x00000100 
00277 #define NODE_F_NODELAY      0x00000200 
00278 #define NODE_F_NOREAD       0x00000400 
00279 #define NODE_F_EOF_WAIT     0x00000800 
00280 #define NODE_F_CLOSING      0x00001000 
00281 #define NODE_F_ULTRA        0x00002000 
00282 #define NODE_F_LEAF         0x00004000 
00283 #define NODE_F_CRAWLER      0x00008000 
00284 #define NODE_F_FAKE_NAME    0x00010000 
00285 #define NODE_F_PROXY        0x00020000 
00286 #define NODE_F_PROXIED      0x00040000 
00287 #define NODE_F_QRP_SENT     0x00080000 
00288 #define NODE_F_TLS          0x00100000 
00289 #define NODE_F_TSYNC_WAIT   0x00200000 
00290 #define NODE_F_TSYNC_TCP    0x00400000 
00291 #define NODE_F_GTKG         0x00800000 
00292 #define NODE_F_FORCE        0x01000000 
00294 /*
00295  * Node attributes.
00296  */
00297 
00298 #define NODE_A_BYE_PACKET   0x00000001 
00299 #define NODE_A_PONG_CACHING 0x00000002 
00300 #define NODE_A_PONG_ALIEN   0x00000004 
00301 #define NODE_A_QHD_NO_VTAG  0x00000008 
00302 #define NODE_A_RX_INFLATE   0x00000010 
00303 #define NODE_A_TX_DEFLATE   0x00000020 
00304 #define NODE_A_ULTRA        0x00000040 
00305 #define NODE_A_NO_ULTRA     0x00000080 
00306 #define NODE_A_UP_QRP       0x00000100 
00307 #define NODE_A_LEAF_GUIDE   0x00000200 
00308 #define NODE_A_TIME_SYNC    0x00000400 
00309 #define NODE_A_CRAWLABLE    0x00000800 
00310 #define NODE_A_DYN_QUERY    0x00001000 
00312 #define NODE_A_NO_DUPS      0x02000000 
00313 #define NODE_A_CAN_HSEP     0x04000000 
00314 #define NODE_A_CAN_QRP      0x08000000 
00315 #define NODE_A_CAN_VENDOR   0x10000000 
00316 #define NODE_A_CAN_GGEP     0x20000000 
00317 #define NODE_A_CAN_ULTRA    0x40000000 
00318 #define NODE_A_CAN_INFLATE  0x80000000 
00320 /*
00321  * UDP crawling "feature" flags.
00322  */
00323 
00324 #define NODE_CR_CONNECTION  0x01        
00325 #define NODE_CR_LOCALE      0x02        
00326 #define NODE_CR_CRAWLABLE   0x04        
00327 #define NODE_CR_USER_AGENT  0x08        
00328 #define NODE_CR_MASK        0x0f        
00330 #define NODE_CR_SEPARATOR   ';'
00331 #define NODE_CR_ESCAPE_CHAR '\\'
00332 
00333 /*
00334  * State inspection macros.
00335  */
00336 
00337 #define NODE_IS_CONNECTING(n)                       \
00338     (   (n)->status == GTA_NODE_CONNECTING          \
00339     ||  (n)->status == GTA_NODE_HELLO_SENT          \
00340     ||  (n)->status == GTA_NODE_WELCOME_SENT        \
00341     ||  (n)->status == GTA_NODE_RECEIVING_HELLO )
00342 
00343 #define NODE_IS_CONNECTED(n)                        \
00344     (   (n)->status == GTA_NODE_CONNECTED           \
00345     ||  (n)->status == GTA_NODE_SHUTDOWN )
00346 
00347 #define NODE_IS_INCOMING(n) \
00348     ((n)->flags & NODE_F_INCOMING)
00349 
00350 #define NODE_IS_REMOVING(n) \
00351     ((n)->status == GTA_NODE_REMOVING)
00352 
00353 #define NODE_IN_TX_FLOW_CONTROL(n) \
00354     ((n)->outq && mq_is_flow_controlled((n)->outq))
00355 
00356 #define NODE_IN_TX_SWIFT_CONTROL(n) \
00357     ((n)->outq && mq_is_swift_controlled((n)->outq))
00358 
00359 #define NODE_IS_WRITABLE(n) \
00360     ((n)->flags & NODE_F_WRITABLE)
00361 
00362 #define NODE_IS_READABLE(n) \
00363     (((n)->flags & (NODE_F_READABLE|NODE_F_NOREAD)) == NODE_F_READABLE)
00364 
00365 #define NODE_IS_ESTABLISHED(n) \
00366     (((n)->flags & (NODE_F_WRITABLE|NODE_F_ESTABLISHED)) == \
00367         (NODE_F_WRITABLE|NODE_F_ESTABLISHED))
00368 
00369 #define NODE_MQUEUE_PERCENT_USED(n) \
00370     ((n)->outq ? mq_size((n)->outq) * 100 / mq_maxsize((n)->outq) : 0)
00371 
00372 #define NODE_SQUEUE(n) ((n)->searchq)
00373 
00374 #define NODE_MQUEUE_COUNT(n) \
00375     ((n)->outq ? mq_count((n)->outq) : 0)
00376 
00377 #define NODE_MQUEUE_PENDING(n) \
00378     ((n)->outq ? mq_pending((n)->outq) : 0)
00379 
00380 #define NODE_MQUEUE_ABOVE_LOWAT(n) \
00381     ((n)->outq ? mq_size((n)->outq) > mq_lowat((n)->outq) : FALSE)
00382 
00383 #define NODE_SQUEUE_COUNT(n) \
00384     ((n)->searchq ? sq_count((n)->searchq) : 0)
00385 
00386 #define NODE_SQUEUE_SENT(n) \
00387     ((n)->searchq ? sq_sent((n)->searchq) : 0)
00388 
00389 #define NODE_RX_COMPRESSED(n) \
00390     ((n)->attrs & NODE_A_RX_INFLATE)
00391 
00392 #define NODE_TX_COMPRESSED(n) \
00393     ((n)->attrs & NODE_A_TX_DEFLATE)
00394 
00395 #define NODE_TX_COMPRESSION_RATIO(n)    \
00396     ((n)->tx_given ?                    \
00397         (double) ((n)->tx_given - (n)->tx_deflated) / (n)->tx_given : 0.0)
00398 
00399 #define NODE_RX_COMPRESSION_RATIO(n)    \
00400     ((n)->rx_inflated ?                 \
00401         (double) ((n)->rx_inflated - (n)->rx_given) / (n)->rx_inflated : 0.0)
00402 
00403 #define NODE_ID(n)              ((n)->id)
00404 
00405 #define NODE_CAN_GGEP(n)        ((n)->attrs & NODE_A_CAN_GGEP)
00406 #define NODE_UP_QRP(n)          ((n)->attrs & NODE_A_UP_QRP)
00407 #define NODE_GUIDES_QUERY(n)    ((n)->attrs & NODE_A_LEAF_GUIDE)
00408 
00409 /*
00410  * Peer inspection macros
00411  */
00412 
00413 #define NODE_IS_LEAF(n)         ((n)->peermode == NODE_P_LEAF)
00414 #define NODE_IS_NORMAL(n)       ((n)->peermode == NODE_P_NORMAL)
00415 #define NODE_IS_ULTRA(n)        ((n)->peermode == NODE_P_ULTRA)
00416 #define NODE_IS_UDP(n)          ((n)->peermode == NODE_P_UDP)
00417 
00418 /*
00419  * Macros.
00420  */
00421 
00422 #define node_vendor(n)      ((n)->vendor != NULL ? (n)->vendor : "????")
00423 #define node_type(n)        \
00424     (NODE_IS_LEAF(n) ? "leaf" : NODE_IS_ULTRA(n) ? "ultra" : "legacy")
00425 
00426 #define node_inc_sent(n)            node_add_sent(n, 1)
00427 #define node_inc_txdrop(n)          node_add_txdrop(n, 1)
00428 #define node_inc_rxdrop(n)          node_add_rxdrop(n, 1)
00429 
00430 #define node_add_tx_given(n,x)      do { (n)->tx_given += (x); } while (0)
00431 #define node_add_rx_read(n,x)       do { (n)->rx_read += (x); } while (0)
00432 
00433 #define node_inc_tx_query(n)        do { (n)->tx_queries++; } while (0)
00434 #define node_inc_rx_query(n)        do { (n)->rx_queries++; } while (0)
00435 #define node_inc_tx_qhit(n)         do { (n)->tx_qhits++; } while (0)
00436 #define node_inc_rx_qhit(n)         do { (n)->rx_qhits++; } while (0)
00437 
00438 #define node_inc_qrp_query(n)       do { (n)->qrp_queries++; } while (0)
00439 #define node_inc_qrp_match(n)       do { (n)->qrp_matches++; } while (0)
00440 
00441 /*
00442  * Check whether Ultra node has received our QRP table, or whether
00443  * we fully got the QRP table from the leaf.
00444  */
00445 #define node_ultra_received_qrp(n) \
00446     (NODE_IS_ULTRA(n) && \
00447     (n)->qrt_update == NULL && (n)->sent_query_table != NULL)
00448 #define node_leaf_sent_qrp(n) \
00449     (NODE_IS_LEAF(n) && \
00450     (n)->qrt_receive == NULL && (n)->recv_query_table != NULL)
00451 
00455 #define node_query_hops_ok(n, h)    ((h) < (n)->hops_flow)
00456 
00473 #define node_flowc_swift_grace(n)   (NODE_IS_LEAF(n) ? 210 : 30)
00474 #define node_flowc_swift_period(n)  (NODE_IS_LEAF(n) ? 140 : 20)
00475 
00476 /*
00477  * Global Data
00478  */
00479 
00480 #define GNUTELLA_HELLO "GNUTELLA CONNECT/"
00481 #define GNUTELLA_HELLO_LENGTH   (sizeof(GNUTELLA_HELLO) - 1)
00482 
00483 #define NODE_ID_LOCAL   0x0U        
00485 extern gchar *start_rfc822_date;
00486 
00487 extern GHookList node_added_hook_list;
00488 extern struct gnutella_node *node_added;
00489 
00490 /*
00491  * Global Functions
00492  */
00493 
00494 void node_init(void);
00495 void node_post_init(void);
00496 void node_slow_timer(time_t now);
00497 void node_timer(time_t now);
00498 guint connected_nodes(void);
00499 guint node_count(void);
00500 guint node_keep_missing(void);
00501 guint node_missing(void);
00502 guint node_leaves_missing(void);
00503 guint node_outdegree(void);
00504 gboolean node_is_connected(const host_addr_t addr, guint16 port,
00505         gboolean incoming);
00506 gboolean node_host_is_connected(const host_addr_t addr, guint16 port);
00507 void node_add_socket(struct gnutella_socket *s, const host_addr_t addr,
00508         guint16 port, guint32 flags);
00509 void node_remove(struct gnutella_node *,
00510     const gchar * reason, ...) G_GNUC_PRINTF(2, 3);
00511 void node_bye(gnutella_node_t *, gint code,
00512     const gchar * reason, ...) G_GNUC_PRINTF(3, 4);
00513 void node_real_remove(gnutella_node_t *);
00514 void node_eof(struct gnutella_node *n,
00515     const gchar * reason, ...) G_GNUC_PRINTF(2, 3);
00516 void node_shutdown(struct gnutella_node *n,
00517     const gchar * reason, ...) G_GNUC_PRINTF(2, 3);
00518 void node_bye_if_writable(struct gnutella_node *n, gint code,
00519     const gchar * reason, ...) G_GNUC_PRINTF(3, 4);
00520 void node_init_outgoing(struct gnutella_node *);
00521 void node_sent_ttl0(struct gnutella_node *n);
00522 void node_disableq(struct gnutella_node *n);
00523 void node_enableq(struct gnutella_node *n);
00524 void node_flushq(struct gnutella_node *n);
00525 void node_unflushq(struct gnutella_node *n);
00526 void node_tx_service(struct gnutella_node *n, gboolean on);
00527 void node_tx_enter_flowc(struct gnutella_node *n);
00528 void node_tx_leave_flowc(struct gnutella_node *n);
00529 void node_tx_enter_warnzone(struct gnutella_node *n);
00530 void node_tx_leave_warnzone(struct gnutella_node *n);
00531 void node_tx_swift_changed(struct gnutella_node *n);
00532 void node_bye_all(void);
00533 gboolean node_bye_pending(void);
00534 void node_close(void);
00535 gboolean node_remove_worst(gboolean non_local);
00536 
00537 void node_qrt_changed(gpointer query_table);
00538 void node_qrt_discard(struct gnutella_node *n);
00539 void node_qrt_install(struct gnutella_node *n, gpointer query_table);
00540 void node_qrt_patched(struct gnutella_node *n, gpointer query_table);
00541 
00542 void send_node_error(struct gnutella_socket *s, int code,
00543     const gchar *msg, ...) G_GNUC_PRINTF(3, 4);
00544 
00545 void node_add_sent(gnutella_node_t *n, gint x);
00546 void node_add_txdrop(gnutella_node_t *n, gint x);
00547 void node_add_rxdrop(gnutella_node_t *n, gint x);
00548 
00549 void node_set_vendor(gnutella_node_t *n, const gchar *vendor);
00550 
00551 void node_set_hops_flow(gnutella_node_t *n, guint8 hops);
00552 void node_set_online_mode(gboolean on);
00553 void node_current_peermode_changed(node_peer_t mode);
00554 const gchar *node_addr(const gnutella_node_t *n);
00555 const gchar *node_gnet_addr(const gnutella_node_t *n);
00556 
00557 void node_connect_back(const gnutella_node_t *n, guint16 port);
00558 void node_connected_back(struct gnutella_socket *s);
00559 
00560 void node_mark_bad_vendor(struct gnutella_node *n);
00561 
00562 void node_proxying_remove(gnutella_node_t *n, gboolean discard);
00563 gboolean node_proxying_add(gnutella_node_t *n, gchar *guid);
00564 void node_proxy_add(gnutella_node_t *n, const host_addr_t addr, guint16 port);
00565 void node_proxy_cancel_all(void);
00566 void node_http_proxies_add(
00567     gchar *buf, gint *retval, gpointer arg, guint32 flags);
00568 GSList *node_push_proxies(void);
00569 const GSList *node_all_nodes(void);
00570 const GSList *node_all_but_broken_gtkg(void);
00571 gnutella_node_t *node_active_by_id(guint32 id);
00572 
00573 void node_became_firewalled(void);
00574 void node_became_udp_firewalled(void);
00575 void node_set_socket_rx_size(gint rx_size);
00576 
00577 mqueue_t *node_udp_get_outq(void);
00578 void node_udp_enable(void);
00579 void node_udp_disable(void);
00580 void node_udp_process(struct gnutella_socket *s);
00581 gnutella_node_t *node_udp_get_addr_port(const host_addr_t addr, guint16 port);
00582 
00583 void node_can_tsync(gnutella_node_t *n);
00584 void node_crawl(gnutella_node_t *n, gint ucnt, gint lcnt, guint8 features);
00585 
00586 void node_update_udp_socket(void);
00587 void node_check_remote_ip_header(const host_addr_t peer, header_t *head);
00588 
00589 guint feed_host_cache_from_headers(header_t *headers,
00590     host_type_t sender, gboolean gnet, const host_addr_t peer);
00591 
00592 gnutella_node_t *node_browse_prepare(
00593     gnet_host_t *host, const gchar *vendor, struct gnutella_header *header,
00594     gchar *data, guint32 size);
00595 void node_browse_cleanup(gnutella_node_t *n);
00596 
00597 #endif /* _core_nodes_h_ */
00598 
00599 /* vi: set ts=4 sw=4 cindent: */

Generated on Sun Feb 12 10:49:57 2006 for Gtk-Gnutella by doxygen 1.3.6