src/net/handler.c \
src/net/listen.c \
src/net/loop.c \
+ src/net/queue.c \
+ src/net/send.c \
src/net/setup.c \
src/net/start.c \
src/net/tcp.c \
src/net/udp.c \
+ src/net/wait.c \
src/opt/config.c \
src/opt/env.c \
src/opt/feed.c \
src/opt/watch.c \
src/opt/worker.c \
src/peer/free.c \
+ src/peer/handshake.c \
src/peer/init.c \
src/pqueue.c \
src/rss/entry.c \
#include<opt.h>
#include<peer.h>
+#include<errno.h>
#include<fcntl.h>
#include<netdb.h>
#include<stdio.h>
hints.ai_next = NULL; \
}
+int net_cache(void**,size_t*,void*,size_t);
void net_handler(int,int,struct peer*);
int net_listen_sock();
void net_loop();
-int net_queue(int,struct peer*,void*,size_t);
+int net_queue(int,int,struct peer*);
+int net_send(int,struct peer*,void*,size_t);
int net_setup(struct net_info*);
int net_start();
int net_tcp();
int net_udp();
-int net_wait(int,struct peer*,size_t);
+int net_wait(int,struct peer*,void*,size_t);
#endif
#define PEER_INFOHASH_SIZE 20
#define PEER_PEER_ID_SIZE 20
+#include<assert.h>
+#include<stddef.h>
+#include<stdint.h>
+#include<stdlib.h>
+#include<string.h>
+
struct peer {
unsigned int handshake : 1;
unsigned int choked : 1;
PEER_MESSAGE_HASH_REJECT = 23
};
+#include<net.h>
+#include<session.h>
+
void peer_free(struct peer*);
int peer_handshake(int,struct peer*);
int peer_init(struct peer**);
if((*prev)!=NULL) {
memcpy(next,(*prev),(*prev_size));
- memcpy(&(next[(*prev_size)]),p,size);
+ memcpy(&(((uint8_t*)next)[(*prev_size)]),p,size);
free((*prev));
}
#include<net.h>
-static ssize_t net_expected_length(int);
-static void send_remaining(int,struct peer*);
+static uint32_t net_expected_length(int);
+static int send_remaining(int,struct peer*);
-static ssize_t net_expected_length(int sock) {
+static uint32_t net_expected_length(int sock) {
unsigned char buf[4];
+ uint32_t len;
ssize_t i;
i = recv(sock,buf,4,MSG_PEEK);
*/
if(i<4) { return 0; }
- i = 0;
+ len = 0;
for(size_t j=0;j<4;j++) {
- i <<= 1;
- i += buf[j];
+ len <<= 1;
+ len += buf[j];
}
return i;
}
-void net_handler(int epoll_fd, int sock, struct peer *peer_info) {
- struct epoll_event ev;
- ssize_t i;
- unsigned int len;
+void net_handler(int epoll_fd, int sock, struct peer *info) {
+ uint32_t i;
if(info->out!=NULL) { goto remaining; }
if((i = net_expected_length(sock))<0) { goto close; }
if(0==i) { goto queue; } // message of length 0 == keep-alive
- switch(buf[4]) {
+ switch(0) {
case PEER_MESSAGE_CHOKE:
break;
case PEER_MESSAGE_UNCHOKE:
return;
remaining:
- if(send_remaining(sock,peer_info)<0) { goto close; }
+ if(send_remaining(sock,info)<0) { goto close; }
goto queue;
handshake:
- if(peer_handshake(sock,peer_info)<0) { goto close; }
+ if(peer_handshake(sock,info)<0) { goto close; }
goto queue;
queue:
- if(net_queue(sock,info,NULL,0)<0) { goto close; }
+ if(net_queue(epoll_fd,sock,info)<0) { goto close; }
return;
close:
- peer_free(peer_info);
+ peer_free(info);
close(sock);
return;
}
static int send_remaining(int sock, struct peer *info) {
- if(net_send(sock,peer_info->out,peer_info->out_size)<0) { return -1; }
+ if(net_send(sock,info,info->out,info->out_size)<0) { return -1; }
free(info->out);
info->out = NULL;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
- if(peer_init((struct peer*)&(ev.data.ptr))<0) {
+ if(peer_init((struct peer**)ev.data.ptr)<0) {
return;
}
#include<net.h>
-int net_queue(int sock, struct peer *info, void *p, size_t size) {
+int net_queue(int epoll_fd, int sock, struct peer *info) {
struct epoll_event ev;
- if((p!=NULL)&&(size>0)) {
- info->data = malloc(size);
- if(NULL==info->data) { return -1; }
-
- memcpy(info->data,p,size);
- }
-
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
ev.data.ptr = info;
ev.data.fd = sock;
#include<net.h>
int net_send(int sock, struct peer *info, void *p, size_t size) {
- void *next;
ssize_t i;
i = send(sock,p,size,0);
return 1;
cache:
- if(net_cache(
- &(info->out), /* void **prev */
- &(info->out_size), /* size_t *prev_size */
- &(p[i]), /* void *p */
- (size-i) /* size_t size */
- )<0) { return -1; }
+ if(p!=info->out) {
+ if(net_cache(
+ &(info->out), /* void **prev */
+ &(info->out_size), /* size_t *prev_size */
+ &(((unsigned char*)p)[i]), /* void *p */
+ (size-i) /* size_t size */
+ )<0) { return -1; }
+ }
return 0;
}
#define HEADER_LENGTH HANDSHAKE_STRING_LENGTH+PEER_INFOHASH_SIZE+PEER_PEER_ID_SIZE
-static int peer_handshake_receive(int);
+static int peer_handshake_receive(int,struct peer*);
int peer_handshake(int sock, struct peer *info) {
char header[HEADER_LENGTH] = HANDSHAKE_STRING;
- int i;
if(sock<0) { return -1; }
- if(peer_handshake_receive(sock)<0) { return -1; }
+ if(peer_handshake_receive(sock,info)<0) { return -1; }
if(!info->handshake) { return 0; }
// copy infohash to buffer
static int peer_handshake_receive(int sock, struct peer *info) {
char header[HEADER_LENGTH];
struct torrent *p;
- ssize_t i;
+ int i;
- if(net_wait(sock,info,header,HEADER_LENGTH)<0) { return -1; }
+ if((i = net_wait(sock,info,header,HEADER_LENGTH))<=0) {
+ if(i<0) { return -1; }
+ return 0;
+ }
memcpy(
info->infohash,
p = session_find_torrent(info->infohash,PEER_INFOHASH_SIZE);
if(NULL==p) { return -1; }
+ info->handshake = 1;
+
return 1;
-wait:
- if(net_wait(sock,info,header,i)<0) { return -1; }
- return 0;
}
hashmap_free(session.torrents.paths);
}
+struct torrent *session_find_torrent(uint8_t *infohash, size_t size) {
+ return NULL;
+}
+
#define SESSION_HASHMAP_INITIAL_SIZE 8
int session_init() {