/* * The QUAFFLER library * Copyright (c) 2006 Clifford Wolf * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _QUAFFLER_H #define _QUAFFLER_H #ifdef __cplusplus extern "C" { #endif /* ------------------ os_unix.h ------------------ */ struct qfl_ctx; // UNIX Socket API with FDs #define QFL_OS_CONNHDL_TYPE int #define QFL_OS_LISTENHDL_TYPE int // UNIX Files API with FDs #define QFL_OS_FILEHDL_TYPE int extern int qfl_os_unix_listen_backlog; #define qfl_os_connection_open qfl_os_unix_connection_open #define qfl_os_connection_close qfl_os_unix_connection_close extern int qfl_os_unix_connection_open(const char *peer, QFL_OS_CONNHDL_TYPE *connhdl_p, int portrange_begin, int portrange_end); extern void qfl_os_unix_connection_close(QFL_OS_CONNHDL_TYPE *connhdl_p); #define qfl_os_listen_open qfl_os_unix_listen_open #define qfl_os_listen_close qfl_os_unix_listen_close extern int qfl_os_unix_listen_open(int *port, QFL_OS_LISTENHDL_TYPE *listenhdl_p, int portrange_begin, int portrange_end); extern void qfl_os_unix_listen_close(QFL_OS_LISTENHDL_TYPE *listenhdl_p); #define qfl_os_accept qfl_os_unix_accept extern struct qfl_conn *qfl_os_unix_accept(struct qfl_ctx *ctx); #define qfl_os_waitfornetwork qfl_os_unix_waitfornetwork extern void qfl_os_unix_waitfornetwork(struct qfl_ctx *ctx, int timeout_ms); #define qfl_os_send qfl_os_unix_send #define qfl_os_recv qfl_os_unix_recv extern int qfl_os_unix_send(QFL_OS_CONNHDL_TYPE *connhdl_p, const unsigned char *data, unsigned int len); extern int qfl_os_unix_recv(QFL_OS_CONNHDL_TYPE *connhdl_p, unsigned char *data, unsigned int len); #define qfl_os_open qfl_os_unix_open #define qfl_os_open_ro qfl_os_unix_open_ro #define qfl_os_close qfl_os_unix_close extern int qfl_os_unix_open(QFL_OS_FILEHDL_TYPE *filehdl_p, const char *filename); extern int qfl_os_unix_open_ro(QFL_OS_FILEHDL_TYPE *filehdl_p, const char *filename); extern void qfl_os_unix_close(QFL_OS_FILEHDL_TYPE *filehdl_p); #define qfl_os_test qfl_os_unix_test #define qfl_os_rename qfl_os_unix_rename extern int qfl_os_unix_test(const char *filename); extern void qfl_os_unix_rename(const char *old_name, const char *new_name); #define qfl_os_read qfl_os_unix_read #define qfl_os_write qfl_os_unix_write extern int qfl_os_unix_read(QFL_OS_FILEHDL_TYPE *filehdl_p, unsigned long long pos, void *data, unsigned int len); extern void qfl_os_unix_write(QFL_OS_FILEHDL_TYPE *filehdl_p, unsigned long long pos, const void *data, unsigned int len); #define qfl_os_getsize qfl_os_unix_getsize #define qfl_os_truncate qfl_os_unix_truncate extern long long qfl_os_unix_getsize(QFL_OS_FILEHDL_TYPE *filehdl_p); extern void qfl_os_unix_truncate(QFL_OS_FILEHDL_TYPE *filehdl_p); #define qfl_os_getrandomid qfl_os_unix_getrandomid #define qfl_os_rand qfl_os_unix_rand #define qfl_os_brand qfl_os_unix_brand extern char *qfl_os_unix_getrandomid(); extern unsigned int qfl_os_unix_rand(); extern void qfl_os_unix_brand(void *s, int n); #define qfl_os_time_ms qfl_os_unix_time_ms extern unsigned long long qfl_os_unix_time_ms(); #define qfl_os_getconfig qfl_os_unix_getconfig #define qfl_os_setconfig qfl_os_unix_setconfig extern char *qfl_os_unix_getconfig(const char *name); extern void qfl_os_unix_setconfig(const char *name, const char *value); /* ------------------ protocol.c ------------------ */ #include "protocol.h" /* ------------------ connection.c ------------------ */ #define QFL_FIFO_IN 0 #define QFL_FIFO_STATUS 1 #define QFL_FIFO_DATA 2 #define QFL_FIFO_COUNT 3 struct qfl_conn; typedef void (*conn_callback)(struct qfl_conn *conn); // 512 MB per second as default rate #define QFL_DEFAULT_RATE_TOTAL (1024*512) struct qfl_ctx { struct qfl_conn *conn_list; int skip_sha1_checks; int skip_crypto; int skip_io; QFL_OS_LISTENHDL_TYPE listenhdl; int listenport; int portrange_begin; int portrange_end; conn_callback process_newconn; unsigned char key_conn_pub[256]; unsigned char key_conn_sec[256]; unsigned char key_identity_pub[256]; unsigned char key_identity_sec[256]; unsigned long long traffic_up, traffic_down; unsigned long long start_timestamp; unsigned long long last_quota_update; long long quota_up, quota_down, quota_total; int rate_up, rate_down, rate_total; }; struct qfl_conn { struct qfl_ctx *ctx; struct qfl_conn *next, *last; int initiator; int closeit; int upload_priority; long long quota; int needs_quota; QFL_OS_CONNHDL_TYPE connhdl; char *peer, *mode; struct qfl_pkgfifo *fifo[QFL_FIFO_COUNT]; int crypto_state; // possible crypto_state value: // responder: // 0 - 255 receiving RSA key // 256 (- 511) sending S-Box, RSA encrypted // 512 - 767 receiving S-Box, OFB encrypted // initiator: // 1024 (- 1279) sending RSA key // 1280 - 1535 receiving S-Box, RSA encrypted // 1536 (- 1791) sending S-Box, OFB encrypted // both: // -1 crypto handshake finished // -2 no crypto unsigned char key_peer_pub[256]; unsigned char input_sbox[258]; unsigned char output_sbox[258]; unsigned char conndrop_flags; unsigned char *senddata; unsigned int senddata_offset; unsigned int senddata_len; conn_callback process_packages; conn_callback process_action; conn_callback process_close; void *appdata; }; extern struct qfl_ctx *qfl_ctx_create(int port, int portrange_begin, int portrange_end); extern void qfl_ctx_destroy(struct qfl_ctx *ctx); extern struct qfl_conn *qfl_conn_create(struct qfl_ctx *ctx, const char *peer); extern void qfl_conn_destroy(struct qfl_conn *conn); extern void qfl_ctx_io_wait(struct qfl_ctx *ctx, int timeout_ms); extern void qfl_ctx_io_process(struct qfl_ctx *ctx); /* ------------------ utils.c ------------------ */ extern char *qfl_getlistentry(const char *list, const char *entry); extern char *qfl_bin2hex(const void *data, int len); extern void qfl_hex2bin(void *data, const char *hex, int len); /* ------------------ join.c ------------------ */ #define QFL_JOIN_ERROR_CONNECT (void*)(unsigned long)1 #define QFL_JOIN_ERROR_URL (void*)(unsigned long)2 #define QFL_JOIN_ERROR_COUNT 2 #define QFL_JOIN_ERROR(x) ((unsigned long)(x) <= QFL_JOIN_ERROR_COUNT) struct qfl_join_conn { struct qfl_join_conn *next; struct qfl_conn *conn, *tracker; int expensive; char *connid; }; struct qfl_join { struct qfl_join *next; struct qfl_join_conn *tracker_list; struct qfl_join_conn *node_list; struct qfl_ctx *ctx; char *quafflerid; char *normalized_quafflerid; char *filename; unsigned char index_sha1[20]; unsigned long long file_size; char frag_scheme; unsigned int block_size; unsigned int chunk_size; unsigned char flags; unsigned int total_blocks; unsigned int chunks_per_block; // one 16bit word per block, with the number of chunks downloaded unsigned short *block_status; unsigned short *block_priority_map; unsigned int size_block_bitmap; unsigned int size_chunk_bitmap; unsigned int size_block_info; unsigned int offset_block_bitmap_complete; unsigned int offset_block_bitmap_progres; unsigned int offset_index_metadata_array; unsigned int offset_block_info; unsigned int offset_attributes; QFL_OS_FILEHDL_TYPE data; QFL_OS_FILEHDL_TYPE qmdf; }; extern struct qfl_join *qfl_join(struct qfl_ctx *ctx, const char *connid, const char *tracker_peer, const char *quafflerid, const char *filename); extern struct qfl_join *qfl_join_by_url(struct qfl_ctx *ctx, const char *connid, const char *url); extern void qfl_join_destroy(struct qfl_join *join); extern void qfl_join_statusdump(struct qfl_join *join); extern void qfl_join_progresdump(struct qfl_join *join); /* ------------------ qmdf.c ------------------ */ extern int qfl_qmdf_generate(const char *filename, const char *trackeraddr, const char *attributes); extern int qfl_qmdf_dump(const char *filename); extern char *qfl_qmdf_to_uri(const char *filename, const char *tracker); /* ------------------ sha1.c ------------------ */ extern void qfl_sha1(const unsigned char *buffer, unsigned int buffer_len, unsigned char *digest); /* ------------------ rsa.c ------------------ */ extern void qfl_rsa_keygen(int bits, unsigned char *pub, unsigned char *sec); extern void qfl_rsa_encrypt(int bits, unsigned char *msg, const unsigned char *pub); extern void qfl_rsa_decrypt(int bits, unsigned char *msg, const unsigned char *pub, const unsigned char *sec); /* ------------------ ofb.c ------------------ */ extern void qfl_ofb_init(unsigned char *sbox); extern void qfl_ofb_recover(unsigned char *sbox); extern void qfl_ofb_xor(unsigned char *sbox, unsigned char *data, int len); #ifdef __cplusplus } #endif #endif