From: victor Date: Tue, 24 Nov 2009 17:11:26 +0000 (+0000) Subject: tabs to spaces X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=aefe74c972aca3dd1e6e7569e081c0f6d9830631;p=swift-upb.git tabs to spaces git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@628 e16421f0-f15b-0410-abcd-98678b794739 --- diff --git a/bin.cpp b/bin.cpp index 0fa7996..7511501 100644 --- a/bin.cpp +++ b/bin.cpp @@ -16,44 +16,44 @@ uint8_t bin::BC[256] = {}; uint8_t bin::T0[256] = {}; void bin::init () { - for(int i=0; i<256; i++) { - int bc=0, bit; - for(bit=0; bit<8; bit++) - if ((i>>bit)&1) bc++; - BC[i] = bc; - for(bit=0; bit<8 && ((i>>bit)&1)==0; bit++); - T0[i] = bit; - } + for(int i=0; i<256; i++) { + int bc=0, bit; + for(bit=0; bit<8; bit++) + if ((i>>bit)&1) bc++; + BC[i] = bc; + for(bit=0; bit<8 && ((i>>bit)&1)==0; bit++); + T0[i] = bit; + } } bin::vec bin::peaks (uint32_t len) { - bin::vec pks; - uint32_t i=len, run=0; - while (i) { - uint32_t bit = bin::highbit(i); - i^=bit; - run |= bit; - pks.push_back(lenpeak(run)); - } - return pks; + bin::vec pks; + uint32_t i=len, run=0; + while (i) { + uint32_t bit = bin::highbit(i); + i^=bit; + run |= bit; + pks.push_back(lenpeak(run)); + } + return pks; } void bin::order (vec* vv) { - vec& v = *vv; - std::sort(v.begin(),v.end()); - std::reverse(v.begin(),v.end()); - vec::iterator pw=v.begin(), pr=v.begin(); - while (pr!=v.end()) { - *pw = *pr; - while (pw!=v.begin() && (pw-1)->sibling()==*pw) { - pw--; - *pw = pw->parent(); - } - bin skipto = *pw - pw->mass(); - while (pr!=v.end() && *pr>skipto) { - pr++; - } - pw++; - } - v.resize(pw-v.begin()); + vec& v = *vv; + std::sort(v.begin(),v.end()); + std::reverse(v.begin(),v.end()); + vec::iterator pw=v.begin(), pr=v.begin(); + while (pr!=v.end()) { + *pw = *pr; + while (pw!=v.begin() && (pw-1)->sibling()==*pw) { + pw--; + *pw = pw->parent(); + } + bin skipto = *pw - pw->mass(); + while (pr!=v.end() && *pr>skipto) { + pr++; + } + pw++; + } + v.resize(pw-v.begin()); } diff --git a/bin.h b/bin.h index ed02494..ca1b3cc 100644 --- a/bin.h +++ b/bin.h @@ -20,217 +20,217 @@ #include struct bin { - uint32_t b; - - static bin NONE; - static bin ALL; - static uint8_t BC[256]; - static uint8_t T0[256]; - - bin() : b(0) {} - bin(const bin& b_) : b(b_.b) {} - bin(uint32_t b_) : b(b_) {} - - bin(uint8_t layer_, uint32_t offset) { - b = lenpeak((offset+1)<>=16; - if ( (i&0xff)==0 ) - ret +=8, i>>=8; - return ret+T0[i&0xff]; - } - - static uint8_t bitcount (uint32_t i) { - //uint8_t* p = (uint8_t*) &i; - //return BC[p[0]] + BC[p[1]] + BC[p[2]] + BC[p[3]]; - return BC[i&0xff] + - BC[(i>>8)&0xff] + - BC[(i>>16)&0xff] + - BC[i>>24]; - } - - static uint32_t blackout (uint32_t i) { - return i|=(i|=(i|=(i|=(i|=i>>1)>>2)>>4)>>8)>>16; - } - - static uint32_t highbit (uint32_t i) { - return (blackout(i)+1)>>1; - } - - static bool all1 (uint32_t a) { - return !(a&(a+1)); - } - - static bin lenpeak (uint32_t length) { - return (length<<1) - bitcount(length); - } - - static uint8_t lenlayer (uint32_t len) { - return tailzeros(len); - } - - static bin layermass (uint8_t layer) { - return (2< vec; - static vec peaks (uint32_t len); - - static void order (vec* v); - - operator uint32_t() const { return b; } - - bin operator ++ () { return b++; } - bin operator -- () { return b--; } - bin operator ++ (int) { return ++b; } - bin operator -- (int) { return --b; } - - uint32_t mlat() const { - return 0; - } - - bin left() const { - return bin(b-(mass()>>1)-1); - } - - bin right() const { - return bin(b-1); - } - - bin right_foot() const { - return bin(b-layer()); - } - - bin left_foot() const { - return bin(b-mass()+1); - } - - uint32_t length() const { - //assert(*this<=ALL); - uint32_t apx = (b>>1) + 16; //if (b<=ALL-32) apx = ALL>>1; - uint32_t next = apx-8; - next = apx = lenpeak(next)>=b ? next : apx; - next -= 4; - next = apx = lenpeak(next)>=b ? next : apx; - next -= 2; - next = apx = lenpeak(next)>=b ? next : apx; - next -= 1; - next = apx = lenpeak(next)>=b ? next : apx; - return apx; - } - - uint32_t mass() const { - return layermass(layer()); - } - - uint8_t layer() const { - uint32_t len = length(); - uint8_t topeak = lenpeak(len) - b; - return lenlayer(len) - topeak; - } - - uint32_t width () const { - return 1<>ls) +1; - uint8_t newlr = std::max(0,layer()-ls); - return lenpeak(newlen) - lenlayer(newlen) + newlr; - } - - uint32_t offset () const { - return length() - width(); - } - - bin modulo (uint8_t ls) const { - if (layer()>=ls) - return layermass(ls); - bin blockleft = lenpeak(((length()-1) & ~((1<b-mass(); - } - - bin commonParent (bin other) const { - uint8_t maxlayer = std::max(layer(),other.layer()); - uint32_t myoff = offset()>>maxlayer, othoff = other.offset()>>maxlayer; - uint32_t diff = blackout(myoff^othoff); - uint8_t toshift = bitcount(diff); - return bin(maxlayer+toshift,myoff>>toshift); - } - - bin child (bin dir) const { - return left().contains(dir) ? left() : right(); - } - - bin parent (uint8_t g=1) const { - uint32_t l = length(); - uint8_t h2b = layer()+g; - uint32_t pbit = 1<parent()==b+1; - } - - bool is_left () const { - return !is_right(); - } - - bin sibling () const { - return is_left() ? bin(b+mass()) : bin(b-mass()); - } - - bin scoped (bin top, uint8_t height) const { - assert(layer()<=top.layer()); // TERRIBLE - assert(top.layer()>=height); - uint8_t rel_layer; - if (layer()+height>=top.layer()) - rel_layer = layer()+height-top.layer(); - else - rel_layer = 0;//top.layer() - height; - uint32_t rel_offset = (offset()-top.offset()) >> (top.layer()-height+rel_layer); - return bin(rel_layer,rel_offset); - } - - bin unscoped (bin top, uint8_t height) const { - uint32_t undermass = layermass(top.layer()-height); - uint32_t pad = (1<b) + pad - undermass*pad; - } + uint32_t b; + + static bin NONE; + static bin ALL; + static uint8_t BC[256]; + static uint8_t T0[256]; + + bin() : b(0) {} + bin(const bin& b_) : b(b_.b) {} + bin(uint32_t b_) : b(b_) {} + + bin(uint8_t layer_, uint32_t offset) { + b = lenpeak((offset+1)<>=16; + if ( (i&0xff)==0 ) + ret +=8, i>>=8; + return ret+T0[i&0xff]; + } + + static uint8_t bitcount (uint32_t i) { + //uint8_t* p = (uint8_t*) &i; + //return BC[p[0]] + BC[p[1]] + BC[p[2]] + BC[p[3]]; + return BC[i&0xff] + + BC[(i>>8)&0xff] + + BC[(i>>16)&0xff] + + BC[i>>24]; + } + + static uint32_t blackout (uint32_t i) { + return i|=(i|=(i|=(i|=(i|=i>>1)>>2)>>4)>>8)>>16; + } + + static uint32_t highbit (uint32_t i) { + return (blackout(i)+1)>>1; + } + + static bool all1 (uint32_t a) { + return !(a&(a+1)); + } + + static bin lenpeak (uint32_t length) { + return (length<<1) - bitcount(length); + } + + static uint8_t lenlayer (uint32_t len) { + return tailzeros(len); + } + + static bin layermass (uint8_t layer) { + return (2< vec; + static vec peaks (uint32_t len); + + static void order (vec* v); + + operator uint32_t() const { return b; } + + bin operator ++ () { return b++; } + bin operator -- () { return b--; } + bin operator ++ (int) { return ++b; } + bin operator -- (int) { return --b; } + + uint32_t mlat() const { + return 0; + } + + bin left() const { + return bin(b-(mass()>>1)-1); + } + + bin right() const { + return bin(b-1); + } + + bin right_foot() const { + return bin(b-layer()); + } + + bin left_foot() const { + return bin(b-mass()+1); + } + + uint32_t length() const { + //assert(*this<=ALL); + uint32_t apx = (b>>1) + 16; //if (b<=ALL-32) apx = ALL>>1; + uint32_t next = apx-8; + next = apx = lenpeak(next)>=b ? next : apx; + next -= 4; + next = apx = lenpeak(next)>=b ? next : apx; + next -= 2; + next = apx = lenpeak(next)>=b ? next : apx; + next -= 1; + next = apx = lenpeak(next)>=b ? next : apx; + return apx; + } + + uint32_t mass() const { + return layermass(layer()); + } + + uint8_t layer() const { + uint32_t len = length(); + uint8_t topeak = lenpeak(len) - b; + return lenlayer(len) - topeak; + } + + uint32_t width () const { + return 1<>ls) +1; + uint8_t newlr = std::max(0,layer()-ls); + return lenpeak(newlen) - lenlayer(newlen) + newlr; + } + + uint32_t offset () const { + return length() - width(); + } + + bin modulo (uint8_t ls) const { + if (layer()>=ls) + return layermass(ls); + bin blockleft = lenpeak(((length()-1) & ~((1<b-mass(); + } + + bin commonParent (bin other) const { + uint8_t maxlayer = std::max(layer(),other.layer()); + uint32_t myoff = offset()>>maxlayer, othoff = other.offset()>>maxlayer; + uint32_t diff = blackout(myoff^othoff); + uint8_t toshift = bitcount(diff); + return bin(maxlayer+toshift,myoff>>toshift); + } + + bin child (bin dir) const { + return left().contains(dir) ? left() : right(); + } + + bin parent (uint8_t g=1) const { + uint32_t l = length(); + uint8_t h2b = layer()+g; + uint32_t pbit = 1<parent()==b+1; + } + + bool is_left () const { + return !is_right(); + } + + bin sibling () const { + return is_left() ? bin(b+mass()) : bin(b-mass()); + } + + bin scoped (bin top, uint8_t height) const { + assert(layer()<=top.layer()); // TERRIBLE + assert(top.layer()>=height); + uint8_t rel_layer; + if (layer()+height>=top.layer()) + rel_layer = layer()+height-top.layer(); + else + rel_layer = 0;//top.layer() - height; + uint32_t rel_offset = (offset()-top.offset()) >> (top.layer()-height+rel_layer); + return bin(rel_layer,rel_offset); + } + + bin unscoped (bin top, uint8_t height) const { + uint32_t undermass = layermass(top.layer()-height); + uint32_t pad = (1<b) + pad - undermass*pad; + } } ; -uint8_t bitcount (uint32_t num); +uint8_t bitcount (uint32_t num); /*bin l=b>a.b?a.b:b, g=b>a.b?b:a.b; while (!g.contains(l)) diff --git a/bins.cpp b/bins.cpp index 3641138..3c4ca6e 100644 --- a/bins.cpp +++ b/bins.cpp @@ -13,7 +13,7 @@ // make it work piece by piece -const uint8_t bins::SPLIT[16] = +const uint8_t bins::SPLIT[16] = {0, 3, 12, 15, 48, 51, 60, 63, 192, 195, 204, 207, 240, 243, 252, 255}; const uint8_t bins::JOIN[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15}; diff --git a/compat.cpp b/compat.cpp index 208828d..f269da2 100644 --- a/compat.cpp +++ b/compat.cpp @@ -37,7 +37,7 @@ int file_seek (int fd, size_t offset) { #ifndef _WIN32 return lseek(fd,offset,SEEK_SET); #else - return _lseek(fd,offset,SEEK_SET); + return _lseek(fd,offset,SEEK_SET); #endif } @@ -76,7 +76,7 @@ void* memory_map (int fd, size_t size) { 0, 0, NULL ); - if (maphandle == NULL) + if (maphandle == NULL) return NULL; map_handles[fd] = maphandle; @@ -95,8 +95,8 @@ void memory_unmap (int fd, void* mapping, size_t size) { munmap(mapping,size); close(fd); #else - UnmapViewOfFile(mapping); - CloseHandle(map_handles[fd]); + UnmapViewOfFile(mapping); + CloseHandle(map_handles[fd]); #endif } @@ -123,8 +123,8 @@ int inet_aton(const char *cp, struct in_addr *inp) tint usec_time(void) { - HiResTimeOfDay* tod = HiResTimeOfDay::Instance(); - return tod->getTimeUSec(); + HiResTimeOfDay* tod = HiResTimeOfDay::Instance(); + return tod->getTimeUSec(); } @@ -133,12 +133,12 @@ tint usec_time(void) tint usec_time(void) { struct timeval t; - gettimeofday(&t,NULL); - tint ret; - ret = t.tv_sec; - ret *= 1000000; - ret += t.tv_usec; - return ret; + gettimeofday(&t,NULL); + tint ret; + ret = t.tv_sec; + ret *= 1000000; + ret += t.tv_usec; + return ret; } #endif diff --git a/compat.h b/compat.h index 39c8808..34a4438 100644 --- a/compat.h +++ b/compat.h @@ -26,9 +26,9 @@ #include #ifdef _WIN32 -#define open(a,b,c) _open(a,b,c) +#define open(a,b,c) _open(a,b,c) #define S_IRUSR _S_IREAD -#define S_IWUSR _S_IWRITE +#define S_IWUSR _S_IWRITE #define S_IRGRP _S_IREAD #define S_IROTH _S_IREAD #endif diff --git a/datagram.cpp b/datagram.cpp index 4d6a4ef..f9bf857 100644 --- a/datagram.cpp +++ b/datagram.cpp @@ -54,8 +54,8 @@ const char* tintstr (tint time) { void Address::set_ipv4 (const char* ip_str) { struct hostent *h = gethostbyname(ip_str); if (h == NULL) { - print_error("cannot lookup address"); - return; + print_error("cannot lookup address"); + return; } else { addr.sin_addr.s_addr = *(u_long *) h->h_addr_list[0]; } @@ -86,142 +86,142 @@ Address::Address(const char* ip_port) { int Datagram::Send () { - int r = sendto(sock,(const char *)buf+offset,length-offset,0, - (struct sockaddr*)&(addr.addr),sizeof(struct sockaddr_in)); + int r = sendto(sock,(const char *)buf+offset,length-offset,0, + (struct sockaddr*)&(addr.addr),sizeof(struct sockaddr_in)); if (r<0) perror("can't send"); - //offset=0; - //length=0; + //offset=0; + //length=0; dgrams_up++; bytes_up+=size(); - Time(); - return r; + Time(); + return r; } int Datagram::Recv () { - socklen_t addrlen = sizeof(struct sockaddr_in); - offset = 0; - length = recvfrom (sock, (char *)buf, MAXDGRAMSZ, 0, - (struct sockaddr*)&(addr.addr), &addrlen); - if (length<0) { + socklen_t addrlen = sizeof(struct sockaddr_in); + offset = 0; + length = recvfrom (sock, (char *)buf, MAXDGRAMSZ, 0, + (struct sockaddr*)&(addr.addr), &addrlen); + if (length<0) { length = 0; print_error("error on recv"); } dgrams_down++; bytes_down+=length; - Time(); - return length; + Time(); + return length; } SOCKET Datagram::Wait (int sockcnt, SOCKET* sockets, tint usec) { - struct timeval timeout; - timeout.tv_sec = usec/TINT_SEC; - timeout.tv_usec = usec%TINT_SEC; - int max_sock_fd = 0; - fd_set bases, err; - FD_ZERO(&bases); - FD_ZERO(&err); - for(int i=0; imax_sock_fd) - max_sock_fd = sockets[i]; - } - int sel = select(max_sock_fd+1, &bases, NULL, &err, &timeout); + struct timeval timeout; + timeout.tv_sec = usec/TINT_SEC; + timeout.tv_usec = usec%TINT_SEC; + int max_sock_fd = 0; + fd_set bases, err; + FD_ZERO(&bases); + FD_ZERO(&err); + for(int i=0; imax_sock_fd) + max_sock_fd = sockets[i]; + } + int sel = select(max_sock_fd+1, &bases, NULL, &err, &timeout); Time(); - if (sel>0) { - for (int i=0; i<=sockcnt; i++) - if (FD_ISSET(sockets[i],&bases)) - return sockets[i]; - } else if (sel<0) { - print_error("select fails"); + if (sel>0) { + for (int i=0; i<=sockcnt; i++) + if (FD_ISSET(sockets[i],&bases)) + return sockets[i]; + } else if (sel<0) { + print_error("select fails"); } return INVALID_SOCKET; } tint Datagram::Time () { - //HiResTimeOfDay* tod = HiResTimeOfDay::Instance(); - //tint ret = tod->getTimeUSec(); - //DLOG(INFO)<<"now is "<getTimeUSec(); + //DLOG(INFO)<<"now is "< #endif #ifdef _WIN32 - #include - #include "compat.h" + #include + #include "compat.h" #else typedef int SOCKET; @@ -107,99 +107,99 @@ struct Address { struct Datagram { - Address addr; - SOCKET sock; - int offset, length; - uint8_t buf[MAXDGRAMSZ*2]; + Address addr; + SOCKET sock; + int offset, length; + uint8_t buf[MAXDGRAMSZ*2]; - static SOCKET Bind(Address address); - static void Close(int port); - static tint Time(); - static SOCKET Wait (int sockcnt, SOCKET* sockets, tint usec=0); - static tint now, epoch, start; + static SOCKET Bind(Address address); + static void Close(int port); + static tint Time(); + static SOCKET Wait (int sockcnt, SOCKET* sockets, tint usec=0); + static tint now, epoch, start; static uint64_t dgrams_up, dgrams_down, bytes_up, bytes_down; - Datagram (SOCKET socket, const Address addr_) : addr(addr_), offset(0), - length(0), sock(socket) {} - Datagram (SOCKET socket) : offset(0), length(0), sock(socket) { - } + Datagram (SOCKET socket, const Address addr_) : addr(addr_), offset(0), + length(0), sock(socket) {} + Datagram (SOCKET socket) : offset(0), length(0), sock(socket) { + } - int space () const { return MAXDGRAMSZ-length; } - int size() const { return length-offset; } - std::string str() const { return std::string((char*)buf+offset,size()); } + int space () const { return MAXDGRAMSZ-length; } + int size() const { return length-offset; } + std::string str() const { return std::string((char*)buf+offset,size()); } const uint8_t* operator * () const { return buf+offset; } - int Push (const uint8_t* data, int l) { // scatter-gather one day - int toc = l>32)); - *(uint32_t*)(buf+length+4) = htonl((uint32_t)(l&0xffffffff)); - length+=8; - } - void PushHash (const Sha1Hash& hash) { - Push((uint8_t*)hash.bits, Sha1Hash::SIZE); - } - - uint8_t Pull8() { - if (size()<1) return 0; - return buf[offset++]; - } - uint16_t Pull16() { - if (size()<2) return 0; - offset+=2; - return ntohs(*(uint16_t*)(buf+offset-2)); - } - uint32_t Pull32() { - if (size()<4) return 0; - uint32_t i = ntohl(*(uint32_t*)(buf+offset)); - offset+=4; - return i; - } - uint64_t Pull64() { - if (size()<8) return 0; - uint64_t l = ntohl(*(uint32_t*)(buf+offset)); - l<<=32; - l |= ntohl(*(uint32_t*)(buf+offset+4)); - offset+=8; - return l; - } - Sha1Hash PullHash() { - if (size()>32)); + *(uint32_t*)(buf+length+4) = htonl((uint32_t)(l&0xffffffff)); + length+=8; + } + void PushHash (const Sha1Hash& hash) { + Push((uint8_t*)hash.bits, Sha1Hash::SIZE); + } + + uint8_t Pull8() { + if (size()<1) return 0; + return buf[offset++]; + } + uint16_t Pull16() { + if (size()<2) return 0; + offset+=2; + return ntohs(*(uint16_t*)(buf+offset-2)); + } + uint32_t Pull32() { + if (size()<4) return 0; + uint32_t i = ntohl(*(uint32_t*)(buf+offset)); + offset+=4; + return i; + } + uint64_t Pull64() { + if (size()<8) return 0; + uint64_t l = ntohl(*(uint32_t*)(buf+offset)); + l<<=32; + l |= ntohl(*(uint32_t*)(buf+offset+4)); + offset+=8; + return l; + } + Sha1Hash PullHash() { + if (size()> 10; + sizek_ = (size_ + 1023) >> 10; peak_count_ = bin64_t::peaks(sizek_,peaks_); int hashes_size = Sha1Hash::SIZE*sizek_*2; file_resize(hash_fd_,hashes_size); @@ -152,7 +152,7 @@ void HashTree::Submit () { for some optimizations. */ void HashTree::RecoverProgress () { size_t size = file_size(fd_); - size_t sizek = (size + 1023) >> 10; + size_t sizek = (size + 1023) >> 10; bin64_t peaks[64]; int peak_count = bin64_t::peaks(sizek,peaks); for(int i=0; i> 10; + sizek_ = (size_ + 1023) >> 10; size_t cur_size = file_size(fd_); if ( cur_size<=(sizek_-1)<<10 || cur_size>sizek_<<10 ) @@ -242,23 +242,23 @@ bool HashTree::OfferPeakHash (bin64_t pos, const Sha1Hash& hash) { Sha1Hash HashTree::DeriveRoot () { - int c = peak_count_-1; - bin64_t p = peaks_[c]; - Sha1Hash hash = peak_hashes_[c]; - c--; - while (p!=bin64_t::ALL) { - if (p.is_left()) { - p = p.parent(); - hash = Sha1Hash(hash,Sha1Hash::ZERO); - } else { - if (c<0 || peaks_[c]!=p.sibling()) - return Sha1Hash::ZERO; - hash = Sha1Hash(peak_hashes_[c],hash); - p = p.parent(); - c--; - } + int c = peak_count_-1; + bin64_t p = peaks_[c]; + Sha1Hash hash = peak_hashes_[c]; + c--; + while (p!=bin64_t::ALL) { + if (p.is_left()) { + p = p.parent(); + hash = Sha1Hash(hash,Sha1Hash::ZERO); + } else { + if (c<0 || peaks_[c]!=p.sibling()) + return Sha1Hash::ZERO; + hash = Sha1Hash(peak_hashes_[c],hash); + p = p.parent(); + c--; + } //dprintf("p %lli %s\n",(uint64_t)p,hash.hex().c_str()); - } + } return hash; } @@ -279,8 +279,8 @@ bin64_t HashTree::peak_for (bin64_t pos) const { bool HashTree::OfferHash (bin64_t pos, const Sha1Hash& hash) { - if (!size_) // only peak hashes are accepted at this point - return OfferPeakHash(pos,hash); + if (!size_) // only peak hashes are accepted at this point + return OfferPeakHash(pos,hash); bin64_t peak = peak_for(pos); if (peak==bin64_t::NONE) return false; @@ -288,7 +288,7 @@ bool HashTree::OfferHash (bin64_t pos, const Sha1Hash& hash) { return hash == hashes_[pos]; if (ack_out_.get(pos.parent())!=bins::EMPTY) return hash==hashes_[pos]; // have this hash already, even accptd data - hashes_[pos] = hash; + hashes_[pos] = hash; if (!pos.is_base()) return false; // who cares? bin64_t p = pos; diff --git a/hashtree.h b/hashtree.h index 77f4b18..e27e2c1 100644 --- a/hashtree.h +++ b/hashtree.h @@ -17,43 +17,43 @@ namespace p2tp { struct Sha1Hash { - uint8_t bits[20]; + uint8_t bits[20]; - Sha1Hash() { memset(bits,0,20); } - Sha1Hash(const Sha1Hash& left, const Sha1Hash& right); - Sha1Hash(const char* str, size_t length=-1); - Sha1Hash(const uint8_t* data, size_t length); - Sha1Hash(bool hex, const char* hash); - - std::string hex() const; - bool operator == (const Sha1Hash& b) const - { return 0==memcmp(bits,b.bits,SIZE); } - bool operator != (const Sha1Hash& b) const { return !(*this==b); } + Sha1Hash() { memset(bits,0,20); } + Sha1Hash(const Sha1Hash& left, const Sha1Hash& right); + Sha1Hash(const char* str, size_t length=-1); + Sha1Hash(const uint8_t* data, size_t length); + Sha1Hash(bool hex, const char* hash); + + std::string hex() const; + bool operator == (const Sha1Hash& b) const + { return 0==memcmp(bits,b.bits,SIZE); } + bool operator != (const Sha1Hash& b) const { return !(*this==b); } const char* operator * () const { return (char*) bits; } - - const static Sha1Hash ZERO; - const static size_t SIZE; + + const static Sha1Hash ZERO; + const static size_t SIZE; }; class HashTree { /** Merkle hash tree: root */ - Sha1Hash root_hash_; + Sha1Hash root_hash_; Sha1Hash *hashes_; /** Merkle hash tree: peak hashes */ Sha1Hash peak_hashes_[64]; bin64_t peaks_[64]; int peak_count_; /** File descriptor to put hashes to */ - int fd_; + int fd_; int hash_fd_; /** Whether to re-hash files. */ bool data_recheck_; /** Base size, as derived from the hashes. */ size_t size_; size_t sizek_; - /** Part of the tree currently checked. */ + /** Part of the tree currently checked. */ size_t complete_; size_t completek_; bins ack_out_; @@ -66,8 +66,8 @@ protected: bool OfferPeakHash (bin64_t pos, const Sha1Hash& hash); public: - - HashTree (const char* file_name, const Sha1Hash& root=Sha1Hash::ZERO, + + HashTree (const char* file_name, const Sha1Hash& root=Sha1Hash::ZERO, const char* hash_filename=NULL); /** Offer a hash; returns true if it verified; false otherwise. @@ -95,10 +95,10 @@ public: bool is_complete () { return size_ && complete_==size_; } bins& ack_out () { return ack_out_; } - - ~HashTree (); + + ~HashTree (); - + }; } diff --git a/p2tp.cpp b/p2tp.cpp index 2ff6504..2de79ba 100644 --- a/p2tp.cpp +++ b/p2tp.cpp @@ -37,8 +37,8 @@ tbheap Channel::send_queue; #include "ext/simple_selector.cpp" PeerSelector* Channel::peer_selector = new SimpleSelector(); -Channel::Channel (FileTransfer* transfer, int socket, Address peer_addr) : - transfer_(transfer), peer_(peer_addr), peer_channel_id_(0), pex_out_(0), +Channel::Channel (FileTransfer* transfer, int socket, Address peer_addr) : + transfer_(transfer), peer_(peer_addr), peer_channel_id_(0), pex_out_(0), socket_(socket==-1?sockets[0]:socket), // FIXME data_out_cap_(bin64_t::ALL), last_send_data_time_(0), last_recv_data_time_(0), own_id_mentioned_(false), next_send_time_(0), last_send_time_(0), @@ -47,8 +47,8 @@ Channel::Channel (FileTransfer* transfer, int socket, Address peer_addr) : { if (peer_==Address()) peer_ = tracker; - this->id = channels.size(); - channels.push_back(this); + this->id = channels.size(); + channels.push_back(this); cc_ = new PingPongController(this); dprintf("%s #%i init %s\n",tintstr(),id,peer_.str()); Schedule(NOW); // FIXME ugly @@ -56,7 +56,7 @@ Channel::Channel (FileTransfer* transfer, int socket, Address peer_addr) : Channel::~Channel () { - channels[id] = NULL; + channels[id] = NULL; delete cc_; } @@ -67,10 +67,10 @@ void p2tp::SetTracker(const Address& tracker) { int Channel::DecodeID(int scrambled) { - return scrambled ^ (int)Datagram::start; + return scrambled ^ (int)Datagram::start; } int Channel::EncodeID(int unscrambled) { - return unscrambled ^ (int)Datagram::start; + return unscrambled ^ (int)Datagram::start; } @@ -117,7 +117,7 @@ int p2tp::Open (const char* filename, const Sha1Hash& hash) { } -void p2tp::Close (int fd) { +void p2tp::Close (int fd) { // FIXME delete all channels if (fd>FileTransfer::files.size() && FileTransfer::files[fd]) delete FileTransfer::files[fd]; @@ -169,14 +169,14 @@ const Sha1Hash& p2tp::RootMerkleHash (int file) { } -/**

P2TP handshake

+/**

P2TP handshake

Basic rules:
    -
  • to send a datagram, a channel must be created +
  • to send a datagram, a channel must be created (channels are cheap and easily recycled) -
  • a datagram must contain either the receiving +
  • a datagram must contain either the receiving channel id (scrambled) or the root hash -
  • initially, the control structure (p2tp_channel) +
  • initially, the control structure (p2tp_channel) is mostly zeroed; intialization happens as conversation progresses
diff --git a/p2tp.h b/p2tp.h index ce5d029..0a872f5 100644 --- a/p2tp.h +++ b/p2tp.h @@ -12,20 +12,20 @@ The P2TP protocol Messages - HANDSHAKE 00, channelid + HANDSHAKE 00, channelid Communicates the channel id of the sender. The initial handshake packet also has the root hash (a HASH message). - DATA 01, bin_32, buffer + DATA 01, bin_32, buffer 1K of data. - ACK 02, bin_32 + ACK 02, bin_32 ACKTS 08, bin_32, timestamp_32 Confirms successfull delivery of data. Used for congestion control, as well. - HINT 03, bin_32 + HINT 03, bin_32 Practical value of "hints" is to avoid overlap, mostly. Hints might be lost in the network or ignored. Peer might send out data without a hint. @@ -34,13 +34,13 @@ Messages As peers cant pick randomly kilobyte here and there, they send out "long hints" for non-base bins. - HASH 04, bin_32, sha1hash + HASH 04, bin_32, sha1hash SHA1 hash tree hashes for data verification. The connection to a fresh peer starts with bootstrapping him with peak hashes. Later, before sending out any data, a peer sends the necessary uncle hashes. - PEX+/PEX- 05/06, ipv4 addr, port + PEX+/PEX- 05/06, ipv4 addr, port Peer exchange messages; reports all connected and disconected peers. Might has special meaning (as in the case with swarm supervisors). @@ -81,7 +81,7 @@ namespace p2tp { { return !(*this==b); } }; - typedef std::deque tbqueue; + typedef std::deque tbqueue; typedef std::deque binqueue; typedef Address Address; @@ -105,32 +105,32 @@ namespace p2tp { } }; - typedef enum { - P2TP_HANDSHAKE = 0, - P2TP_DATA = 1, - P2TP_ACK = 2, - P2TP_TS = 8, - P2TP_HINT = 3, - P2TP_HASH = 4, - P2TP_PEX_ADD = 5, - P2TP_PEX_RM = 6, - P2TP_MESSAGE_COUNT = 7 - } messageid_t; + typedef enum { + P2TP_HANDSHAKE = 0, + P2TP_DATA = 1, + P2TP_ACK = 2, + P2TP_TS = 8, + P2TP_HINT = 3, + P2TP_HASH = 4, + P2TP_PEX_ADD = 5, + P2TP_PEX_RM = 6, + P2TP_MESSAGE_COUNT = 7 + } messageid_t; class PiecePicker; class CongestionController; class PeerSelector; - class FileTransfer { + class FileTransfer { public: - /** Open/submit/retrieve a file. */ + /** Open/submit/retrieve a file. */ FileTransfer(const char *file_name, const Sha1Hash& _root_hash=Sha1Hash::ZERO); - /** Close everything. */ - ~FileTransfer(); + /** Close everything. */ + ~FileTransfer(); /** While we need to feed ACKs to every peer, we try (1) avoid @@ -141,7 +141,7 @@ namespace p2tp { int RevealChannel (int& i); static FileTransfer* Find (const Sha1Hash& hash); - static FileTransfer* file (int fd) { + static FileTransfer* file (int fd) { return fd files; + static std::vector files; HashTree file_; @@ -175,14 +175,14 @@ namespace p2tp { void OnDataIn (bin64_t pos); void OnPexIn (const Address& addr); - friend class Channel; + friend class Channel; friend uint64_t Size (int fdes); friend bool IsComplete (int fdes); friend uint64_t Complete (int fdes); friend uint64_t SeqComplete (int fdes); friend int Open (const char* filename, const Sha1Hash& hash) ; friend void Close (int fd) ; - }; + }; #include "ext/send_control.h" @@ -210,38 +210,38 @@ namespace p2tp { }; - /** P2TP channel's "control block"; channels loosely correspond to TCP + /** P2TP channel's "control block"; channels loosely correspond to TCP connections or FTP sessions; one channel is created for one file being transferred between two peers. As we don't need buffers and lots of other TCP stuff, sizeof(Channel+members) must be below 1K. (There was a seductive idea to remove channels, just put the root hash or a fragment of it into every datagram.) */ - struct Channel { // normally, API users do not deal with the structure + struct Channel { // normally, API users do not deal with the structure - Channel (FileTransfer* file, int socket=-1, Address peer=Address()); - ~Channel(); + Channel (FileTransfer* file, int socket=-1, Address peer=Address()); + ~Channel(); - static void RecvDatagram (int socket); + static void RecvDatagram (int socket); static void Loop (tint till); - void Recv (Datagram& dgram); - void Send (); - - void OnAck (Datagram& dgram); - void OnTs (Datagram& dgram); - bin64_t OnData (Datagram& dgram); - void OnHint (Datagram& dgram); - void OnHash (Datagram& dgram); - void OnPex (Datagram& dgram); - void OnHandshake (Datagram& dgram); - void AddHandshake (Datagram& dgram); - bin64_t AddData (Datagram& dgram); - void AddAck (Datagram& dgram); - void AddTs (Datagram& dgram); - void AddHint (Datagram& dgram); - void AddUncleHashes (Datagram& dgram, bin64_t pos); - void AddPeakHashes (Datagram& dgram); - void AddPex (Datagram& dgram); + void Recv (Datagram& dgram); + void Send (); + + void OnAck (Datagram& dgram); + void OnTs (Datagram& dgram); + bin64_t OnData (Datagram& dgram); + void OnHint (Datagram& dgram); + void OnHash (Datagram& dgram); + void OnPex (Datagram& dgram); + void OnHandshake (Datagram& dgram); + void AddHandshake (Datagram& dgram); + bin64_t AddData (Datagram& dgram); + void AddAck (Datagram& dgram); + void AddTs (Datagram& dgram); + void AddHint (Datagram& dgram); + void AddUncleHashes (Datagram& dgram, bin64_t pos); + void AddPeakHashes (Datagram& dgram); + void AddPex (Datagram& dgram); const std::string id_string () const; /** A channel is "established" if had already sent and received packets. */ @@ -250,45 +250,45 @@ namespace p2tp { HashTree& file () { return transfer_->file(); } const Address& peer() const { return peer_; } - static int DecodeID(int scrambled); - static int EncodeID(int unscrambled); - static Channel* channel(int i) { + static int DecodeID(int scrambled); + static int EncodeID(int unscrambled); + static Channel* channel(int i) { return i channels; + static std::vector channels; friend int Listen (Address addr); friend void Shutdown (int sock_des); @@ -330,7 +330,7 @@ namespace p2tp { friend class FileTransfer; // FIXME!!! friend class SendController; // FIXME!!! - }; + }; @@ -348,7 +348,7 @@ namespace p2tp { /** Get the root hash for the transmission. */ const Sha1Hash& RootMerkleHash (int file) ; /** Close a file and a transmission. */ - void Close (int fd) ; + void Close (int fd) ; /** Add a possible peer which participares in a given transmission. In the case root hash is zero, the peer might be talked to regarding any transmission (likely, a tracker, cache or an archive). */ @@ -368,11 +368,11 @@ namespace p2tp { uint64_t SeqComplete (int fdes); - //uint32_t Width (const tbinvec& v); + //uint32_t Width (const tbinvec& v); - /** Must be called by any client using the library */ - void LibraryInit(void); + /** Must be called by any client using the library */ + void LibraryInit(void); } // namespace end diff --git a/rarest1st.cpp b/rarest1st.cpp index 87627e9..16c9b8b 100644 --- a/rarest1st.cpp +++ b/rarest1st.cpp @@ -8,36 +8,36 @@ */ -char* Rarest1st::on_event (P2Channel& ch) { - if (!ch.peer_has) - return "nothing is known - cannot choose"; - feye i_need (ch.file->have,ch.peer_has->focus); - i_need.invert(); - i_need &= ch.peer_has; - if (i_need.clean()) - return "the peer has nothing we don't have"; - feye ladder[20]; - for(int i=P2TP_CHANNELS.begin(); i!=P2TP_CHANNELS.end(); i++) { - p2tp_channel* c = *i; - if (!c || !c->peer_has) - continue; - feye x = feye_and(c->peer_has,i_need); - for(int j=0; j<20 && !x.clean(); j++) { - feye xx(x); - x &= ladder[j]; - ladder[j] ^= xx; - } - } - feye not_rare (ch.peer_has->focus); - for(int i=20-1; i>0; i--) { - not_rare |= ladder[i]; - ladder[i-1] -= not_rare; - } - int pickfrom = 0; - while (ladder[pickfrom].clean() && pickfrom<20) - pickfrom++; - assert(pickfrom<20); - mlat spot = ladder[pickfrom].randomBit(); - ch->i_ackd.refocus(spot); - return NULL; +char* Rarest1st::on_event (P2Channel& ch) { + if (!ch.peer_has) + return "nothing is known - cannot choose"; + feye i_need (ch.file->have,ch.peer_has->focus); + i_need.invert(); + i_need &= ch.peer_has; + if (i_need.clean()) + return "the peer has nothing we don't have"; + feye ladder[20]; + for(int i=P2TP_CHANNELS.begin(); i!=P2TP_CHANNELS.end(); i++) { + p2tp_channel* c = *i; + if (!c || !c->peer_has) + continue; + feye x = feye_and(c->peer_has,i_need); + for(int j=0; j<20 && !x.clean(); j++) { + feye xx(x); + x &= ladder[j]; + ladder[j] ^= xx; + } + } + feye not_rare (ch.peer_has->focus); + for(int i=20-1; i>0; i--) { + not_rare |= ladder[i]; + ladder[i-1] -= not_rare; + } + int pickfrom = 0; + while (ladder[pickfrom].clean() && pickfrom<20) + pickfrom++; + assert(pickfrom<20); + mlat spot = ladder[pickfrom].randomBit(); + ch->i_ackd.refocus(spot); + return NULL; } diff --git a/sbit.cpp b/sbit.cpp index f21ff8f..a03715e 100644 --- a/sbit.cpp +++ b/sbit.cpp @@ -8,225 +8,225 @@ */ #include "sbit.h" -uint16_t bins::SPLIT[256]; -uint8_t bins::JOIN[256]; -uint16_t bins::OFFMASK[32]; +uint16_t bins::SPLIT[256]; +uint8_t bins::JOIN[256]; +uint16_t bins::OFFMASK[32]; static uint16_t NO_PARENT = 0xffff; bins::bins () : peak(31), bits(32,0), deep(32,false), prnt(16,NO_PARENT), - allocp(1), rescan_flag(true) { - prnt[0] = 0; - deep[1] = true; + allocp(1), rescan_flag(true) { + prnt[0] = 0; + deep[1] = true; } bins::bins(const bins& b) : peak(b.peak), allocp(b.allocp), - bits(b.bits), prnt(b.prnt), deep(b.deep), rescan_flag(b.rescan_flag) + bits(b.bits), prnt(b.prnt), deep(b.deep), rescan_flag(b.rescan_flag) { } -void bins::init () { - for(int i=0; i<256; i++) - JOIN[i] = 0xff; - for(int i=0; i<256; i++) { - int split = 0; - for(int b=0; b<8; b++) - if (i&(1<peak) - return false; - chunk_iterator i(const_cast(this)); - while (i.deep() && i.chunk_top()>pos) - i.to(pos); - if (i.deep()) - return false; - int l = OFFMASK[pos.scoped(i.chunk_top(),4)]; - return (*i & l) == l; +bool bins::get(bin pos) const { + if (pos>peak) + return false; + chunk_iterator i(const_cast(this)); + while (i.deep() && i.chunk_top()>pos) + i.to(pos); + if (i.deep()) + return false; + int l = OFFMASK[pos.scoped(i.chunk_top(),4)]; + return (*i & l) == l; } -bool bins::clean(bin pos) const { - if (pos>peak) - return bin::all1(pos) ? clean(peak) : true; - chunk_iterator i(const_cast(this)); - while (i.deep() && i.chunk_top()>pos) - i.to(pos); - if (i.deep()) - return false; - int l = OFFMASK[pos.scoped(i.chunk_top(),4)]; - return (*i & l) == 0; +bool bins::clean(bin pos) const { + if (pos>peak) + return bin::all1(pos) ? clean(peak) : true; + chunk_iterator i(const_cast(this)); + while (i.deep() && i.chunk_top()>pos) + i.to(pos); + if (i.deep()) + return false; + int l = OFFMASK[pos.scoped(i.chunk_top(),4)]; + return (*i & l) == 0; } -void bins::expand () { - int oldrootcell = cell_alloc(); - if (deep[0]) - prnt[bits[0]] = oldrootcell; - prnt[oldrootcell] = 0; - int orl = oldrootcell<<1, orr = orl+1; - bits[orl] = bits[0]; - bits[orr] = 0; - bits[0] = oldrootcell; - deep[orl] = deep[0]; - deep[orr] = false; - deep[0] = true; - peak = peak.parent(); - compact(0); +void bins::expand () { + int oldrootcell = cell_alloc(); + if (deep[0]) + prnt[bits[0]] = oldrootcell; + prnt[oldrootcell] = 0; + int orl = oldrootcell<<1, orr = orl+1; + bits[orl] = bits[0]; + bits[orr] = 0; + bits[0] = oldrootcell; + deep[orl] = deep[0]; + deep[orr] = false; + deep[0] = true; + peak = peak.parent(); + compact(0); } -void bins::set (bin pos, bool to) { - if (!pos) - return; - while (pos>peak) - expand(); - chunk_iterator i(this); - while (i.chunk_top().layer()>pos.layer()+4) - i.to(pos); - while (i.deep() && i.chunk_top().layer()>pos.layer()) - i.to(pos); - if (i.deep()) - unlink(i.half); - int mask = OFFMASK[pos.scoped(i.chunk_top(),4)]; - if (to) - *i |= mask; - else - *i &= ~mask; - while(i.up()); //compact +void bins::set (bin pos, bool to) { + if (!pos) + return; + while (pos>peak) + expand(); + chunk_iterator i(this); + while (i.chunk_top().layer()>pos.layer()+4) + i.to(pos); + while (i.deep() && i.chunk_top().layer()>pos.layer()) + i.to(pos); + if (i.deep()) + unlink(i.half); + int mask = OFFMASK[pos.scoped(i.chunk_top(),4)]; + if (to) + *i |= mask; + else + *i &= ~mask; + while(i.up()); //compact } -bool bins::compact (int half) { - if (!deep[half]) - return false; - int l = bits[half]<<1, r = l+1; - if (deep[l] || deep[r]) - return false; - int l1 = JOIN[bits[l]&0xff], l2 = JOIN[bits[l]>>8]; - if (l1==0xff || l2==0xff) - return false; - int r1 = JOIN[bits[r]&0xff], r2 = JOIN[bits[r]>>8]; - if (r1==0xff || r2==0xff) - return false; - deep[half] = false; - prnt[bits[half]] = NO_PARENT; - deep[l] = deep[r] = false;//coward - bits[half] = (l1) | (l2<<4) | (r1<<8) | (r2<<12); - return true; +bool bins::compact (int half) { + if (!deep[half]) + return false; + int l = bits[half]<<1, r = l+1; + if (deep[l] || deep[r]) + return false; + int l1 = JOIN[bits[l]&0xff], l2 = JOIN[bits[l]>>8]; + if (l1==0xff || l2==0xff) + return false; + int r1 = JOIN[bits[r]&0xff], r2 = JOIN[bits[r]>>8]; + if (r1==0xff || r2==0xff) + return false; + deep[half] = false; + prnt[bits[half]] = NO_PARENT; + deep[l] = deep[r] = false;//coward + bits[half] = (l1) | (l2<<4) | (r1<<8) | (r2<<12); + return true; } -void bins::split (int half) { - if (!deep[half]) { - int newcell = cell_alloc(), oldcell=half>>1; - int l = newcell<<1, r = l+1; - bits[l] = SPLIT[bits[half]&0xff]; - bits[r] = SPLIT[bits[half]>>8]; - deep[half] = true; - bits[half] = newcell; - prnt[newcell] = oldcell; - } +void bins::split (int half) { + if (!deep[half]) { + int newcell = cell_alloc(), oldcell=half>>1; + int l = newcell<<1, r = l+1; + bits[l] = SPLIT[bits[half]&0xff]; + bits[r] = SPLIT[bits[half]>>8]; + deep[half] = true; + bits[half] = newcell; + prnt[newcell] = oldcell; + } } -void bins::doop (bins& b, int op) { - while (b.peakpeak) - expand(); - chunk_iterator i(this), j(&b); - do { - while (i.deep() || j.deep()) { - i.left(); - j.left(); - } - switch (op) { - case OR_OP: (*i) |= *j; break; - case AND_OP: (*i) &= *j; break; - case SUB_OP: (*i) &= ~*j; break; - } - while (i.chunk_top().is_right()) { - i.up(); - j.up(); - } - i.up(); - j.up(); - i.right(); - j.right(); - } while (!i.end()); +void bins::doop (bins& b, int op) { + while (b.peakpeak) + expand(); + chunk_iterator i(this), j(&b); + do { + while (i.deep() || j.deep()) { + i.left(); + j.left(); + } + switch (op) { + case OR_OP: (*i) |= *j; break; + case AND_OP: (*i) &= *j; break; + case SUB_OP: (*i) &= ~*j; break; + } + while (i.chunk_top().is_right()) { + i.up(); + j.up(); + } + i.up(); + j.up(); + i.right(); + j.right(); + } while (!i.end()); } -void bins::operator |= (bins& b) { - doop(b,OR_OP); +void bins::operator |= (bins& b) { + doop(b,OR_OP); } -void bins::operator &= (bins& b) { - doop(b,AND_OP); +void bins::operator &= (bins& b) { + doop(b,AND_OP); } -void bins::operator -= (bins& b) { - doop(b,SUB_OP); +void bins::operator -= (bins& b) { + doop(b,SUB_OP); } -int bins::cell_alloc () { // FIXME: 0xffff size too big - while (allocp renames(allocp), irenames(allocp); int newcellsize=0; for(int i=0; i>1; - half=host->prnt[cell]<<1; - if (!host->deep[half] || host->bits[half]!=cell) - half++; - assert(host->deep[half] && host->bits[half]==cell); - return host->compact(half); - } - void left() { - assert(top.layer()>4); - top = top.left(); - if (!deep()) - host->split(half); - half = host->bits[half]<<1; - } - void right() { - assert(top.layer()>4); - top = top.right(); - if (!deep()) - host->split(half); - half = (host->bits[half]<<1)+1; - } - void to(bin target) { - assert(top.layer()>4); - bin next = top.child(target); - if (next.is_left()) - left(); - else - right(); - } - int cell () const { return half>>1; } - bool deep() const { return host->deep[half]; } - bool is_right () const { return half&1; } - bool end () const { return half==1; } + class bin_iterator; + + /** Traverses 16-bit chunks. */ + class chunk_iterator { + bins* host; + bin top; + int half; + + bool up() { + top=top.parent(); + int cell = half>>1; + half=host->prnt[cell]<<1; + if (!host->deep[half] || host->bits[half]!=cell) + half++; + assert(host->deep[half] && host->bits[half]==cell); + return host->compact(half); + } + void left() { + assert(top.layer()>4); + top = top.left(); + if (!deep()) + host->split(half); + half = host->bits[half]<<1; + } + void right() { + assert(top.layer()>4); + top = top.right(); + if (!deep()) + host->split(half); + half = (host->bits[half]<<1)+1; + } + void to(bin target) { + assert(top.layer()>4); + bin next = top.child(target); + if (next.is_left()) + left(); + else + right(); + } + int cell () const { return half>>1; } + bool deep() const { return host->deep[half]; } + bool is_right () const { return half&1; } + bool end () const { return half==1; } - public: - chunk_iterator(bins* h, int hlf=0) : host(h), top(h->peak), half(hlf) { - //while (deep()) - // left(); - } - void operator ++ () { - while (is_right()) - up(); - up(); - right(); - while (deep() && !end()) - left(); - } - uint16_t& operator * () { - return host->bits[half]; - } - bool operator == (const bins::chunk_iterator& b) const { - return host==b.host && half==b.half; - } - bin chunk_top() const { return top; } - friend class bins::bin_iterator; - friend class bins; - }; // chunk_iterator - - - /** Traverses bins. */ - class bin_iterator { - bins::chunk_iterator i; - bin cur; - public: - bin_iterator(chunk_iterator ci, bin pos=0) : i(ci), cur(pos) { - while (!i.end() && i.deep()) - i.left(); - ++(*this); - } - bin operator * () const { - return cur.unscoped(i.top,4); - } - void operator ++ () { - if (i.end()) - return; - do { - if (curpeak), half(hlf) { + //while (deep()) + // left(); + } + void operator ++ () { + while (is_right()) + up(); + up(); + right(); + while (deep() && !end()) + left(); + } + uint16_t& operator * () { + return host->bits[half]; + } + bool operator == (const bins::chunk_iterator& b) const { + return host==b.host && half==b.half; + } + bin chunk_top() const { return top; } + friend class bins::bin_iterator; + friend class bins; + }; // chunk_iterator + + + /** Traverses bins. */ + class bin_iterator { + bins::chunk_iterator i; + bin cur; + public: + bin_iterator(chunk_iterator ci, bin pos=0) : i(ci), cur(pos) { + while (!i.end() && i.deep()) + i.left(); + ++(*this); + } + bin operator * () const { + return cur.unscoped(i.top,4); + } + void operator ++ () { + if (i.end()) + return; + do { + if (cur bits; - std::vector prnt; // BAD BAD BAD - std::vector deep; - int allocp; - bool rescan_flag; + bin peak; + std::vector bits; + std::vector prnt; // BAD BAD BAD + std::vector deep; + int allocp; + bool rescan_flag; - + private: - - void unlink (int half); - void expand(); - void split(int half); - - //void make_space(); - int cell_alloc(); - bool compact (int cell); - - void doop (bins& b, int op); - - static uint16_t SPLIT[256]; - static uint8_t JOIN[256]; - static uint16_t OFFMASK[32]; - typedef enum { AND_OP, OR_OP, SUB_OP } ops_t; - + + void unlink (int half); + void expand(); + void split(int half); + + //void make_space(); + int cell_alloc(); + bool compact (int cell); + + void doop (bins& b, int op); + + static uint16_t SPLIT[256]; + static uint8_t JOIN[256]; + static uint16_t OFFMASK[32]; + typedef enum { AND_OP, OR_OP, SUB_OP } ops_t; + public: - - bins(); - bins(const bins& orig); - - bool get(bin pos) const; - bool clean(bin pos) const; - bool contains(bin pos) const { return get(pos); } - void set(bin pos, bool to=true); - bool empty() const { return !deep[0] && !bits[0]; } - bool operator [] (bin pos) const {return get(pos);} - void operator |= (bin pos) { set(pos); } - void operator -= (bin pos) { set(pos,false); } - void operator |= (bins& b); - void operator &= (bins& b); - void operator -= (bins& b); - - bin_iterator begin() { return bin_iterator(chunk_iterator(this,0)); } - bin_iterator end() { return bin_iterator(chunk_iterator(this,1),1); } - - static void init(); - friend class SbitTest; + + bins(); + bins(const bins& orig); + + bool get(bin pos) const; + bool clean(bin pos) const; + bool contains(bin pos) const { return get(pos); } + void set(bin pos, bool to=true); + bool empty() const { return !deep[0] && !bits[0]; } + bool operator [] (bin pos) const {return get(pos);} + void operator |= (bin pos) { set(pos); } + void operator -= (bin pos) { set(pos,false); } + void operator |= (bins& b); + void operator &= (bins& b); + void operator -= (bins& b); + + bin_iterator begin() { return bin_iterator(chunk_iterator(this,0)); } + bin_iterator end() { return bin_iterator(chunk_iterator(this,1),1); } + + static void init(); + friend class SbitTest; }; diff --git a/sendrecv.cpp b/sendrecv.cpp index 7506751..6ac587a 100644 --- a/sendrecv.cpp +++ b/sendrecv.cpp @@ -19,26 +19,26 @@ using namespace std; // FIXME remove - randomized testing of advanced ops (new testcase) */ -void Channel::AddPeakHashes (Datagram& dgram) { - for(int i=0; iMaySendData()) { tosend = DequeueHint(); if (tosend==bin64_t::NONE) @@ -192,35 +192,35 @@ bin64_t Channel::AddData (Datagram& dgram) { data_out_.push_back(tosend); dprintf("%s #%i +data %s\n",tintstr(),id,tosend.str()); - return tosend; + return tosend; } -void Channel::AddTs (Datagram& dgram) { +void Channel::AddTs (Datagram& dgram) { dgram.Push8(P2TP_TS); dgram.Push64(data_in_.time); dprintf("%s #%i +ts %s\n",tintstr(),id,tintstr(data_in_.time)); } -void Channel::AddAck (Datagram& dgram) { +void Channel::AddAck (Datagram& dgram) { if (data_in_dbl_!=bin64_t::NONE) { - dgram.Push8(P2TP_ACK); - dgram.Push32(data_in_dbl_); + dgram.Push8(P2TP_ACK); + dgram.Push32(data_in_dbl_); data_in_dbl_=bin64_t::NONE; } - if (data_in_.bin!=bin64_t::NONE) { + if (data_in_.bin!=bin64_t::NONE) { AddTs(dgram); bin64_t pos = file().ack_out().cover(data_in_.bin); - dgram.Push8(P2TP_ACK); - dgram.Push32(pos); - //dgram.Push64(data_in_.time); + dgram.Push8(P2TP_ACK); + dgram.Push32(pos); + //dgram.Push64(data_in_.time); ack_out_.set(pos); dprintf("%s #%i +ack %s %s\n",tintstr(),id,pos.str(),tintstr(data_in_.time)); data_in_ = tintbin(0,bin64_t::NONE); if (pos.layer()>2) data_in_dbl_ = pos; - } + } for(int count=0; count<4; count++) { bin64_t ack = file().ack_out().find_filtered(ack_out_, bin64_t::ALL, bins::FILLED); if (ack==bin64_t::NONE) @@ -234,7 +234,7 @@ void Channel::AddAck (Datagram& dgram) { } -void Channel::Recv (Datagram& dgram) { +void Channel::Recv (Datagram& dgram) { dprintf("%s #%i recvd %i\n",tintstr(),id,dgram.size()+4); if (last_send_time_ && rtt_avg_==TINT_SEC && dev_avg_==0) { rtt_avg_ = NOW - last_send_time_; @@ -244,30 +244,30 @@ void Channel::Recv (Datagram& dgram) { dprintf("%s #%i rtt init %lli\n",tintstr(),id,rtt_avg_); } bin64_t data = dgram.size() ? bin64_t::NONE : bin64_t::ALL; - while (dgram.size()) { - uint8_t type = dgram.Pull8(); - switch (type) { + while (dgram.size()) { + uint8_t type = dgram.Pull8(); + switch (type) { case P2TP_HANDSHAKE: OnHandshake(dgram); break; - case P2TP_DATA: data=OnData(dgram); break; - case P2TP_TS: OnTs(dgram); break; - case P2TP_ACK: OnAck(dgram); break; - case P2TP_HASH: OnHash(dgram); break; - case P2TP_HINT: OnHint(dgram); break; + case P2TP_DATA: data=OnData(dgram); break; + case P2TP_TS: OnTs(dgram); break; + case P2TP_ACK: OnAck(dgram); break; + case P2TP_HASH: OnHash(dgram); break; + case P2TP_HINT: OnHint(dgram); break; case P2TP_PEX_ADD: OnPex(dgram); break; - default: - eprintf("%s #%i ?msg id unknown %i\n",tintstr(),id,(int)type); - return; - } - } + default: + eprintf("%s #%i ?msg id unknown %i\n",tintstr(),id,(int)type); + return; + } + } cc_->OnDataRecvd(data); last_recv_time_ = NOW; } -void Channel::OnHash (Datagram& dgram) { - bin64_t pos = dgram.Pull32(); - Sha1Hash hash = dgram.PullHash(); - file().OfferHash(pos,hash); +void Channel::OnHash (Datagram& dgram) { + bin64_t pos = dgram.Pull32(); + Sha1Hash hash = dgram.PullHash(); + file().OfferHash(pos,hash); //DLOG(INFO)<<"#"<=file().packet_size()) { eprintf("invalid ack: %s\n",ackd_pos.str()); return; @@ -385,9 +385,9 @@ void Channel::OnTs (Datagram& dgram) { } -void Channel::OnHint (Datagram& dgram) { - bin64_t hint = dgram.Pull32(); - hint_in_.push_back(hint); +void Channel::OnHint (Datagram& dgram) { + bin64_t hint = dgram.Pull32(); + hint_in_.push_back(hint); //ack_in_.set(hint,bins::EMPTY); //RequeueSend(cc_->OnHintRecvd(hint)); dprintf("%s #%i -hint %s\n",tintstr(),id,hint.str()); @@ -422,53 +422,53 @@ void Channel::AddPex (Datagram& dgram) { } -void Channel::RecvDatagram (int socket) { - Datagram data(socket); - data.Recv(); +void Channel::RecvDatagram (int socket) { + Datagram data(socket); + data.Recv(); Address& addr = data.addr; #define return_log(...) { eprintf(__VA_ARGS__); return; } - if (data.size()<4) - return_log("datagram shorter than 4 bytes %s\n",addr.str()); - uint32_t mych = data.Pull32(); - Sha1Hash hash; - Channel* channel = NULL; - if (!mych) { // handshake initiated - if (data.size()<1+4+1+4+Sha1Hash::SIZE) - return_log ("incorrect size %i initial handshake packet %s\n",data.size(),addr.str()); - uint8_t hashid = data.Pull8(); - if (hashid!=P2TP_HASH) - return_log ("no hash in the initial handshake %s\n",addr.str()); - bin64_t pos = data.Pull32(); - if (pos!=bin64_t::ALL) - return_log ("that is not the root hash %s\n",addr.str()); - hash = data.PullHash(); - FileTransfer* file = FileTransfer::Find(hash); - if (!file) - return_log ("hash %s unknown, no such file %s\n",hash.hex().c_str(),addr.str()); + if (data.size()<4) + return_log("datagram shorter than 4 bytes %s\n",addr.str()); + uint32_t mych = data.Pull32(); + Sha1Hash hash; + Channel* channel = NULL; + if (!mych) { // handshake initiated + if (data.size()<1+4+1+4+Sha1Hash::SIZE) + return_log ("incorrect size %i initial handshake packet %s\n",data.size(),addr.str()); + uint8_t hashid = data.Pull8(); + if (hashid!=P2TP_HASH) + return_log ("no hash in the initial handshake %s\n",addr.str()); + bin64_t pos = data.Pull32(); + if (pos!=bin64_t::ALL) + return_log ("that is not the root hash %s\n",addr.str()); + hash = data.PullHash(); + FileTransfer* file = FileTransfer::Find(hash); + if (!file) + return_log ("hash %s unknown, no such file %s\n",hash.hex().c_str(),addr.str()); dprintf("%s #0 -hash ALL %s\n",tintstr(),hash.hex().c_str()); for(binqueue::iterator i=file->hs_in_.begin(); i!=file->hs_in_.end(); i++) if (channels[*i] && channels[*i]->peer_==data.addr && channels[*i]->last_recv_time_>NOW-TINT_SEC*2) return_log("have a channel already to %s\n",addr.str()); - channel = new Channel(file, socket, data.address()); - } else { - mych = DecodeID(mych); - if (mych>=channels.size()) + channel = new Channel(file, socket, data.address()); + } else { + mych = DecodeID(mych); + if (mych>=channels.size()) return_log("invalid channel #%i, %s\n",mych,addr.str()); - channel = channels[mych]; - if (!channel) - return_log ("channel #%i is already closed\n",mych,addr.str()); - if (channel->peer() != addr) - return_log ("invalid peer address #%i %s!=%s\n",mych,channel->peer().str(),addr.str()); + channel = channels[mych]; + if (!channel) + return_log ("channel #%i is already closed\n",mych,addr.str()); + if (channel->peer() != addr) + return_log ("invalid peer address #%i %s!=%s\n",mych,channel->peer().str(),addr.str()); channel->own_id_mentioned_ = true; - } + } //dprintf("recvd %i bytes for %i\n",data.size(),channel->id); channel->Recv(data); } void Channel::Loop (tint howlong) { - + tint limit = Datagram::Time() + howlong; do { @@ -509,7 +509,7 @@ void Channel::Loop (tint howlong) { } } while (Datagram::Time()> (r))) -#define SHA_ROL(X,n) SHA_ROT(X,n,32-(n)) -#define SHA_ROR(X,n) SHA_ROT(X,32-(n),n) +#define SHA_ROT(X,l,r) (((X) << (l)) | ((X) >> (r))) +#define SHA_ROL(X,n) SHA_ROT(X,n,32-(n)) +#define SHA_ROR(X,n) SHA_ROT(X,32-(n),n) #endif @@ -80,22 +80,22 @@ defined(__powerpc__) || defined(__powerpc64__) || \ defined(__s390__) || defined(__s390x__) -#define get_be32(p) ntohl(*(unsigned int *)(p)) -#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0) +#define get_be32(p) ntohl(*(unsigned int *)(p)) +#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0) #else -#define get_be32(p) ( \ - (*((unsigned char *)(p) + 0) << 24) | \ - (*((unsigned char *)(p) + 1) << 16) | \ - (*((unsigned char *)(p) + 2) << 8) | \ - (*((unsigned char *)(p) + 3) << 0) ) -#define put_be32(p, v) do { \ - unsigned int __v = (v); \ - *((unsigned char *)(p) + 0) = __v >> 24; \ - *((unsigned char *)(p) + 1) = __v >> 16; \ - *((unsigned char *)(p) + 2) = __v >> 8; \ - *((unsigned char *)(p) + 3) = __v >> 0; } while (0) +#define get_be32(p) ( \ + (*((unsigned char *)(p) + 0) << 24) | \ + (*((unsigned char *)(p) + 1) << 16) | \ + (*((unsigned char *)(p) + 2) << 8) | \ + (*((unsigned char *)(p) + 3) << 0) ) +#define put_be32(p, v) do { \ + unsigned int __v = (v); \ + *((unsigned char *)(p) + 0) = __v >> 24; \ + *((unsigned char *)(p) + 1) = __v >> 16; \ + *((unsigned char *)(p) + 2) = __v >> 8; \ + *((unsigned char *)(p) + 3) = __v >> 0; } while (0) #endif @@ -110,9 +110,9 @@ #define SHA_MIX(t) SHA_ROL(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1) #define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \ - unsigned int TEMP = input(t); setW(t, TEMP); \ - E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \ - B = SHA_ROR(B, 2); } while (0) + unsigned int TEMP = input(t); setW(t, TEMP); \ + E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \ + B = SHA_ROR(B, 2); } while (0) #define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) #define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) @@ -122,167 +122,167 @@ static void blk_SHA1_Block(blk_SHA_CTX *ctx, const unsigned int *data) { - unsigned int A,B,C,D,E; - unsigned int array[16]; - - A = ctx->H[0]; - B = ctx->H[1]; - C = ctx->H[2]; - D = ctx->H[3]; - E = ctx->H[4]; - - /* Round 1 - iterations 0-16 take their input from 'data' */ - T_0_15( 0, A, B, C, D, E); - T_0_15( 1, E, A, B, C, D); - T_0_15( 2, D, E, A, B, C); - T_0_15( 3, C, D, E, A, B); - T_0_15( 4, B, C, D, E, A); - T_0_15( 5, A, B, C, D, E); - T_0_15( 6, E, A, B, C, D); - T_0_15( 7, D, E, A, B, C); - T_0_15( 8, C, D, E, A, B); - T_0_15( 9, B, C, D, E, A); - T_0_15(10, A, B, C, D, E); - T_0_15(11, E, A, B, C, D); - T_0_15(12, D, E, A, B, C); - T_0_15(13, C, D, E, A, B); - T_0_15(14, B, C, D, E, A); - T_0_15(15, A, B, C, D, E); - - /* Round 1 - tail. Input from 512-bit mixing array */ - T_16_19(16, E, A, B, C, D); - T_16_19(17, D, E, A, B, C); - T_16_19(18, C, D, E, A, B); - T_16_19(19, B, C, D, E, A); - - /* Round 2 */ - T_20_39(20, A, B, C, D, E); - T_20_39(21, E, A, B, C, D); - T_20_39(22, D, E, A, B, C); - T_20_39(23, C, D, E, A, B); - T_20_39(24, B, C, D, E, A); - T_20_39(25, A, B, C, D, E); - T_20_39(26, E, A, B, C, D); - T_20_39(27, D, E, A, B, C); - T_20_39(28, C, D, E, A, B); - T_20_39(29, B, C, D, E, A); - T_20_39(30, A, B, C, D, E); - T_20_39(31, E, A, B, C, D); - T_20_39(32, D, E, A, B, C); - T_20_39(33, C, D, E, A, B); - T_20_39(34, B, C, D, E, A); - T_20_39(35, A, B, C, D, E); - T_20_39(36, E, A, B, C, D); - T_20_39(37, D, E, A, B, C); - T_20_39(38, C, D, E, A, B); - T_20_39(39, B, C, D, E, A); - - /* Round 3 */ - T_40_59(40, A, B, C, D, E); - T_40_59(41, E, A, B, C, D); - T_40_59(42, D, E, A, B, C); - T_40_59(43, C, D, E, A, B); - T_40_59(44, B, C, D, E, A); - T_40_59(45, A, B, C, D, E); - T_40_59(46, E, A, B, C, D); - T_40_59(47, D, E, A, B, C); - T_40_59(48, C, D, E, A, B); - T_40_59(49, B, C, D, E, A); - T_40_59(50, A, B, C, D, E); - T_40_59(51, E, A, B, C, D); - T_40_59(52, D, E, A, B, C); - T_40_59(53, C, D, E, A, B); - T_40_59(54, B, C, D, E, A); - T_40_59(55, A, B, C, D, E); - T_40_59(56, E, A, B, C, D); - T_40_59(57, D, E, A, B, C); - T_40_59(58, C, D, E, A, B); - T_40_59(59, B, C, D, E, A); - - /* Round 4 */ - T_60_79(60, A, B, C, D, E); - T_60_79(61, E, A, B, C, D); - T_60_79(62, D, E, A, B, C); - T_60_79(63, C, D, E, A, B); - T_60_79(64, B, C, D, E, A); - T_60_79(65, A, B, C, D, E); - T_60_79(66, E, A, B, C, D); - T_60_79(67, D, E, A, B, C); - T_60_79(68, C, D, E, A, B); - T_60_79(69, B, C, D, E, A); - T_60_79(70, A, B, C, D, E); - T_60_79(71, E, A, B, C, D); - T_60_79(72, D, E, A, B, C); - T_60_79(73, C, D, E, A, B); - T_60_79(74, B, C, D, E, A); - T_60_79(75, A, B, C, D, E); - T_60_79(76, E, A, B, C, D); - T_60_79(77, D, E, A, B, C); - T_60_79(78, C, D, E, A, B); - T_60_79(79, B, C, D, E, A); - - ctx->H[0] += A; - ctx->H[1] += B; - ctx->H[2] += C; - ctx->H[3] += D; - ctx->H[4] += E; + unsigned int A,B,C,D,E; + unsigned int array[16]; + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + /* Round 1 - iterations 0-16 take their input from 'data' */ + T_0_15( 0, A, B, C, D, E); + T_0_15( 1, E, A, B, C, D); + T_0_15( 2, D, E, A, B, C); + T_0_15( 3, C, D, E, A, B); + T_0_15( 4, B, C, D, E, A); + T_0_15( 5, A, B, C, D, E); + T_0_15( 6, E, A, B, C, D); + T_0_15( 7, D, E, A, B, C); + T_0_15( 8, C, D, E, A, B); + T_0_15( 9, B, C, D, E, A); + T_0_15(10, A, B, C, D, E); + T_0_15(11, E, A, B, C, D); + T_0_15(12, D, E, A, B, C); + T_0_15(13, C, D, E, A, B); + T_0_15(14, B, C, D, E, A); + T_0_15(15, A, B, C, D, E); + + /* Round 1 - tail. Input from 512-bit mixing array */ + T_16_19(16, E, A, B, C, D); + T_16_19(17, D, E, A, B, C); + T_16_19(18, C, D, E, A, B); + T_16_19(19, B, C, D, E, A); + + /* Round 2 */ + T_20_39(20, A, B, C, D, E); + T_20_39(21, E, A, B, C, D); + T_20_39(22, D, E, A, B, C); + T_20_39(23, C, D, E, A, B); + T_20_39(24, B, C, D, E, A); + T_20_39(25, A, B, C, D, E); + T_20_39(26, E, A, B, C, D); + T_20_39(27, D, E, A, B, C); + T_20_39(28, C, D, E, A, B); + T_20_39(29, B, C, D, E, A); + T_20_39(30, A, B, C, D, E); + T_20_39(31, E, A, B, C, D); + T_20_39(32, D, E, A, B, C); + T_20_39(33, C, D, E, A, B); + T_20_39(34, B, C, D, E, A); + T_20_39(35, A, B, C, D, E); + T_20_39(36, E, A, B, C, D); + T_20_39(37, D, E, A, B, C); + T_20_39(38, C, D, E, A, B); + T_20_39(39, B, C, D, E, A); + + /* Round 3 */ + T_40_59(40, A, B, C, D, E); + T_40_59(41, E, A, B, C, D); + T_40_59(42, D, E, A, B, C); + T_40_59(43, C, D, E, A, B); + T_40_59(44, B, C, D, E, A); + T_40_59(45, A, B, C, D, E); + T_40_59(46, E, A, B, C, D); + T_40_59(47, D, E, A, B, C); + T_40_59(48, C, D, E, A, B); + T_40_59(49, B, C, D, E, A); + T_40_59(50, A, B, C, D, E); + T_40_59(51, E, A, B, C, D); + T_40_59(52, D, E, A, B, C); + T_40_59(53, C, D, E, A, B); + T_40_59(54, B, C, D, E, A); + T_40_59(55, A, B, C, D, E); + T_40_59(56, E, A, B, C, D); + T_40_59(57, D, E, A, B, C); + T_40_59(58, C, D, E, A, B); + T_40_59(59, B, C, D, E, A); + + /* Round 4 */ + T_60_79(60, A, B, C, D, E); + T_60_79(61, E, A, B, C, D); + T_60_79(62, D, E, A, B, C); + T_60_79(63, C, D, E, A, B); + T_60_79(64, B, C, D, E, A); + T_60_79(65, A, B, C, D, E); + T_60_79(66, E, A, B, C, D); + T_60_79(67, D, E, A, B, C); + T_60_79(68, C, D, E, A, B); + T_60_79(69, B, C, D, E, A); + T_60_79(70, A, B, C, D, E); + T_60_79(71, E, A, B, C, D); + T_60_79(72, D, E, A, B, C); + T_60_79(73, C, D, E, A, B); + T_60_79(74, B, C, D, E, A); + T_60_79(75, A, B, C, D, E); + T_60_79(76, E, A, B, C, D); + T_60_79(77, D, E, A, B, C); + T_60_79(78, C, D, E, A, B); + T_60_79(79, B, C, D, E, A); + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; } void blk_SHA1_Init(blk_SHA_CTX *ctx) { - ctx->size = 0; - - /* Initialize H with the magic constants (see FIPS180 for constants) */ - ctx->H[0] = 0x67452301; - ctx->H[1] = 0xefcdab89; - ctx->H[2] = 0x98badcfe; - ctx->H[3] = 0x10325476; - ctx->H[4] = 0xc3d2e1f0; + ctx->size = 0; + + /* Initialize H with the magic constants (see FIPS180 for constants) */ + ctx->H[0] = 0x67452301; + ctx->H[1] = 0xefcdab89; + ctx->H[2] = 0x98badcfe; + ctx->H[3] = 0x10325476; + ctx->H[4] = 0xc3d2e1f0; } void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len) { - int lenW = ctx->size & 63; - - ctx->size += len; - - /* Read the data into W and process blocks as they get full */ - if (lenW) { - int left = 64 - lenW; - if (len < left) - left = len; - memcpy(lenW + (char *)ctx->W, data, left); - lenW = (lenW + left) & 63; - len -= left; - data = ((const char *)data + left); - if (lenW) - return; - blk_SHA1_Block(ctx, ctx->W); - } - while (len >= 64) { - blk_SHA1_Block(ctx, (const unsigned int*)data); - data = ((const char *)data + 64); - len -= 64; - } - if (len) - memcpy(ctx->W, data, len); + int lenW = ctx->size & 63; + + ctx->size += len; + + /* Read the data into W and process blocks as they get full */ + if (lenW) { + int left = 64 - lenW; + if (len < left) + left = len; + memcpy(lenW + (char *)ctx->W, data, left); + lenW = (lenW + left) & 63; + len -= left; + data = ((const char *)data + left); + if (lenW) + return; + blk_SHA1_Block(ctx, ctx->W); + } + while (len >= 64) { + blk_SHA1_Block(ctx, (const unsigned int*)data); + data = ((const char *)data + 64); + len -= 64; + } + if (len) + memcpy(ctx->W, data, len); } void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx) { - static const unsigned char pad[64] = { 0x80 }; - unsigned int padlen[2]; - int i; + static const unsigned char pad[64] = { 0x80 }; + unsigned int padlen[2]; + int i; - /* Pad with a binary 1 (ie 0x80), then zeroes, then length */ - padlen[0] = htonl(ctx->size >> 29); - padlen[1] = htonl(ctx->size << 3); + /* Pad with a binary 1 (ie 0x80), then zeroes, then length */ + padlen[0] = htonl(ctx->size >> 29); + padlen[1] = htonl(ctx->size << 3); - i = ctx->size & 63; - blk_SHA1_Update(ctx, pad, 1+ (63 & (55 - i))); - blk_SHA1_Update(ctx, padlen, 8); + i = ctx->size & 63; + blk_SHA1_Update(ctx, pad, 1+ (63 & (55 - i))); + blk_SHA1_Update(ctx, padlen, 8); - /* Output hash */ - for (i = 0; i < 5; i++) - put_be32(hashout + i*4, ctx->H[i]); + /* Output hash */ + for (i = 0; i < 5; i++) + put_be32(hashout + i*4, ctx->H[i]); } diff --git a/sha1.h b/sha1.h index 5fc8c98..844ea53 100644 --- a/sha1.h +++ b/sha1.h @@ -9,9 +9,9 @@ #define GIT_SHA1 typedef struct { - unsigned long long size; - unsigned int H[5]; - unsigned int W[16]; + unsigned long long size; + unsigned int H[5]; + unsigned int W[16]; } blk_SHA_CTX; void blk_SHA1_Init(blk_SHA_CTX *ctx);