...
authoralex <[email protected]>
Thu, 24 Mar 2022 00:32:00 +0000 (17:32 -0700)
committeralex <[email protected]>
Thu, 24 Mar 2022 00:32:00 +0000 (17:32 -0700)
inc/peer.h
src/net/wait.c

index 7c73326e91997f33e0ffd0534242f71804be543e..36c117e72554afeec0804479f3524e834432ed79 100644 (file)
@@ -12,8 +12,11 @@ struct peer {
        uint8_t infohash[PEER_INFOHASH_SIZE];
        unsigned char peer_id[PEER_PEER_ID_SIZE];
 
-       void *data;
-       size_t data_size;
+       void *out;
+       size_t out_size;
+
+       void *in;
+       size_t in_size;
 };
 
 enum peer_message {
index 9979ca81eb45c269a4bfd34e56fa2e96600840dc..cfa5936be490febdcf06f5d8ea35f766c3bd13a9 100644 (file)
@@ -1,10 +1,72 @@
 #include<net.h>
 
-int net_wait(int sock, struct peer *info, void *p, size_t size) {
-       return -1;
-       /*if(-1==i) {
+static int cache(struct peer*,void*,size_t);
+static void* use_cached(struct peer*,void*,size_t*);
+
+static int cache(struct peer *info, void *p, size_t size) {
+       void *next;
+       size_t i;
+
+       next_size = (info->in!=NULL) ? size + info->in_size : size;
+       next = malloc(next_size);
+       if(NULL==next) { return -1; }
+
+       memcpy(next,p,size);
+       if(info->in!=NULL) {
+               memcpy(&(next[size]),info->in,info->in_size);
+               free(info->in);
+       }
+
+       info->in = next;
+       info->in_size = next_size;
+
+       return 1;
+}
+
+int net_wait(int sock, struct peer *info, void *buf, size_t buf_size) {
+       void *p;
+       size_t size;
+       ssize_t i;
+       
+       size = buf_size;
+       p = use_cached(info,buf,&size);
+
+       i = recv(sock,p,size,0);
+       if(-1==i) {
                if(!((errno==EAGAIN)||(errno==EWOULDBLOCK))) {
                        perror("recv");
                        return -1;
-               }*/
+               }
+       }
+
+       if((i!=size)&&(size>0)) { goto cached; }
+
+       return 1;
+cached:
+       cache(info,p,i+(buf_size - size));
+       return 0;
+}
+
+static void *use_cached(struct peer *info,void *p,size_t *size) {
+       if(info->in!=NULL) {
+               if(info->in_size>(*size)) {
+                       /* some cached left over */
+                       memcpy(p,info->in,*size);
+                       p += (*size);
+                       
+                       info->in_size -= *size;
+                       memmove(info->in,&(info[*size]),info->in_size);
+                       *size = 0;
+               } else {
+                       /* use up all cached data */
+                       memcpy(p,info->in,info->in_size);
+                       free(info->in);
+                       info->in = NULL;
+
+                       *size -= info->in_size;
+                       p += info->in_size;
+               }
+       }
+
+       return p;
 }