#define __NET_H_
#include<opt.h>
+#include<peer.h>
#include<fcntl.h>
#include<netdb.h>
hints.ai_next = NULL; \
}
-void net_handler();
+void net_handler(int,int,struct peer*);
int net_listen_sock();
void net_loop();
int net_setup(struct net_info*);
#ifndef __PEER_H_
#define __PEER_H_
+struct peer {
+ unsigned int choked : 1;
+ unsigned int interested: 1;
+
+ uint8_t infohash[20];
+ unsigned char peer_id[20];
+};
+
enum peer_message {
PEER_MESSAGE_CHOKE = 0,
PEER_MESSAGE_UNCHOKE = 1,
PEER_MESSAGE_HASH_REJECT = 23
};
-int peer_handshake(int,const uint8_t*,size_t,const uint8_t*,size_t);
+int peer_handshake(int,struct peer*);
+int peer_init(struct peer**);
#endif
struct session {
struct session_torrents torrents;
+ unsigned char peer_id[20];
};
extern struct session session;
#include<net.h>
-void net_handler(int sock) {
- char buf[5];
+void net_handler(int epoll_fd, int sock, struct peer *peer_info) {
+ struct epoll_event ev;
+ unsigned char buf[4];
ssize_t i;
unsigned int len;
- i = recv(sock,buf,5,MSG_PEEK);
+ if(NULL==peer_info) {
+ if(peer_init(&peer_info)<0) { goto close; }
+ if(peer_handshake(sock,peer_info)<0) { goto close; }
+ goto epoll;
+ }
+
+ i = recv(sock,buf,4,MSG_PEEK);
if(-1==i) {
if(!((errno==EAGAIN)||(errno==EWOULDBLOCK))) {
perror("recv");
return;
}
+ goto epoll;
}
+ /*
+ * message should at least have 4 bytes (length prefix of
+ * the following message)
+ */
+ if(i<4) { goto epoll; }
+
len = 0;
for(size_t i=0;i<4;i++) {
len <<= 1;
}
return;
+close:
+ if(peer_info!=NULL) { peer_free(peer_info); }
+ close(sock);
+ return;
+epoll:
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.ptr = peer_info;
+ ev.data.fd = sock;
+
+ if(-1==epoll_ctl(epoll_fd,EPOLL_CTL_ADD,sock,&ev)) {
+ perror("epoll_ctl");
+ return;
+ }
}
setnonblocking(conn_sock);
ev.events = EPOLLIN | EPOLLET;
+ ev.data.ptr = NULL;
ev.data.fd = conn_sock;
if(-1==epoll_ctl(info->epoll_fd,EPOLL_CTL_ADD,conn_sock,&ev)) {
return;
}
} else {
- net_handler(events[n].data.fd);
+ net_handler(info->epoll_fd,events[n].data.fd,events[n].data.ptr);
}
}
}
#define HANDSHAKE_STRING "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\0";
#define HANDSHAKE_INFOHASH_SIZE 20
-int peer_handshake(int sock, const uint8_t *infohash, size_t infohash_size const uint8_t *peer_id, size_t peer_id_size) {
+int peer_handshake(int sock, struct peer **info) {
+ ssize_t i;
const char header[64] = HANDSHAKE_STRING;
+
+
assert(HANDSHAKE_INFOHASH_SIZE==infohash_size);
assert(PEER_ID_SIZE==peer_id_size);