--- /dev/null
+#include<peer.h>
+
+#define HANDSHAKE_STRING "\x13BitTorrent protocol\0\0\0\0\0\0\0\0";
+#define HANDSHAKE_INFOHASH_SIZE 20
+
+int handshake(int sock, const uint8_t *infohash, size_t infohash_size const uint8_t peer_id, size_t peer_id_size) {
+ const char header[64] = HANDSHAKE_STRING;
+
+ memcpy(&(header[24]),infohash,HANDSHAKE_INFOHASH_SIZE);
+ memcpy(&(header[44]),peer_id,PEER_ID_SIZE);
+
+ if(sock<0) { return -1; }
+
+ // send header
+
+ return -1;
+}
struct session session;
+static int session_torrent_add_by_infohash(struct torrent*);
+static int session_torrent_add_by_path(struct torrent*);
+static int session_torrent_resize(struct hash_map**,size_t);
+
void session_clean() {
- struct torrent *torrent_p;
- if(session.torrents!=NULL) {
- while(session.torrent_count>0) {
- torrent_p = session.torrents[session.torrent_count];
- if(torrent_p!=NULL) { torrent_free(torrent_p); }
- session.torrent_count--;
- }
- }
- free(session.torrents);
+ // clear infohashes so no double-free
+ hashmap_clear(session.torrent.infohashes);
+
+ hashmap_free(session.torrent.infohashes);
+ hashmap_free(session.torrent.paths);
}
int session_init() {
- session.torrents = NULL;
- session.torrent_count = 0;
+ if(hashmap_init(session.torrents.infohashes,SESSION_HASHMAP_INITIAL_SIZE)<0) { return -1; }
+ if(hashmap_init(session.torrents.paths,SESSION_HASHMAP_INITIAL_SIZE)<0) { return -1; }
return 1;
}
int session_torrent_add(struct torrent *p) {
- size_t new_count;
+ while((i = session_torrent_add_by_infohash(p))<=0) {
+ if(i<0) { return -1; }
+ if(session_torrent_resize(
+ &(session.torrent.infohashes), /* map */
+ session.torrent.infohashes.size<<1 /* new_size */
+ )<0) { return -1; }
+ }
+
+ while((i = session_torrent_add_by_path(p))<=0) {
+ if(i<0) { return -1; }
+ if(session_torrent_resize(
+ &(session.torrent.paths), /* map */
+ session.torrent.paths.size<<1 /* new_size */
+ )<0) { return -1; }
+ }
+
+ return 1;
+}
- if((NULL==session.torrents)||(session.torrent_count%SESSION_REALLOC_COUNT==0)) {
- new_count = session.torrent_count+SESSION_REALLOC_COUNT;
- log_info(SESSION_MESSAGE_REALLOC_COUNT,new_count);
+static int session_torrent_add_by_infohash(struct torrent *torrent) {
+ struct torrent *p;
+ int i;
- session.torrents = realloc(session.torrents,sizeof(struct torrent*)*new_count);
- if(NULL==session.torrents) {
- perror("realloc");
- return -1;
- }
+ if((i = hashmap_insert(session.torrents.infohashes,torrent->infohash,crypto_hash_sha_256_BYTES,p))<=0) {
+ if(i<0) { return -1; }
- for(size_t i=session.torrent_count;i<new_count;i++) {
- session.torrents[i] = NULL;
- }
+ p = hashmap_find(session.torrents.infohashes,torrent->infohash,crypto_hash_sha_256_BYTES);
+ if((p!=NULL)&&(memcmp(torrent->infohash,p->infohash,crypto_hash_sha256_BYTES)!=0)) { return 0; }
}
- session.torrents[session.torrent_count] = p;
- session.torrent_count++;
+ return 1;
+}
+
+static int session_torrent_add_by_path(struct torrent *torrent) {
+ struct torrent *p;
+ int i;
+
+ if((i = hashmap_insert(session.torrents.paths,torrent->root,strlen(torrent->root),p))<=0) {
+ if(i<0) { return -1; }
+
+ p = hashmap_find(session.torrents.paths,torrent->root,strlen(torrent->root));
+ if((p!=NULL)&&(strcmp(p->root,torrent->root)!=0)) { return 0; }
+ }
return 1;
}
+
+static int session_torrent_resize(struct hash_map **map, size_t new_size) {
+ return -1;
+}