00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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"
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
00089
00090 #define CACHE_HOP_IDX(h) (((h) > MAX_CACHE_HOPS) ? MAX_CACHE_HOPS : (h))
00091
00092
00093
00094
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
00194
00195
00196
00197
00198 guint32 tcp_rtt;
00199 guint32 udp_rtt;
00200 gpointer tsync_ev;
00202
00203
00204
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
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
00244
00245
00246
00247
00248
00249
00250
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
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
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
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
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
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
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
00443
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
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
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
00598
00599