diff --git a/Changes b/Changes index af26ec5c7..e70118915 100644 --- a/Changes +++ b/Changes @@ -1830,3 +1830,6 @@ seen. gmtime warning still there - Added some missing oflags for SVSO. Reported by auspice (#0000671) - Possibly fixed the throttling bug reported by Jaw959 (#0000644) - Fixed triple WATCH reply bug (#0000632) +- Added ZIP_LINKS support, no check in ./Config & configure yet.. you currently need to + add -lz to IRCDLIBS in Makefile and enable it in include/config.h (and ofcourse set + link::options::zip on both sides) -- Syzop. diff --git a/include/common.h b/include/common.h index 2b25a72c1..40af228a8 100644 --- a/include/common.h +++ b/include/common.h @@ -335,5 +335,6 @@ TS now; #endif #endif +#define READBUF_SIZE 8192 #endif /* __common_include__ */ diff --git a/include/config.h b/include/config.h index 24d4c5f24..900815e99 100644 --- a/include/config.h +++ b/include/config.h @@ -516,6 +516,15 @@ */ #undef FAST_BADWORD_REPLACE +/* + * Enable zipped links? [EXPERIMENTAL] + */ +#undef ZIP_LINKS +/* If you use ziplinks, you can define the compression level here, + * higher=better compressed but more CPU time, can be 1-9, but 1-4 is suggested. + */ +#define ZIP_LEVEL 2 + /* ------------------------- END CONFIGURATION SECTION -------------------- */ #define MOTD MPATH #define RULES RPATH diff --git a/include/h.h b/include/h.h index f5b792abc..3e295c30e 100644 --- a/include/h.h +++ b/include/h.h @@ -521,7 +521,7 @@ extern char *oflagstr(long oflag); extern int rehash(aClient *cptr, aClient *sptr, int sig); extern int _match(char *mask, char *name); extern void outofmemory(void); -extern unsigned long crc32(const unsigned char *s, unsigned int len); +extern unsigned long our_crc32(const unsigned char *s, unsigned int len); extern int add_listener2(ConfigItem_listen *conf); extern void link_cleanup(ConfigItem_link *link_ptr); extern void listen_cleanup(); diff --git a/include/struct.h b/include/struct.h index 6c6f1b7ec..6ff3d5263 100644 --- a/include/struct.h +++ b/include/struct.h @@ -127,6 +127,10 @@ typedef struct SMember Member; typedef struct SMembership Membership; typedef struct SMembershipL MembershipL; +#ifdef ZIP_LINKS +typedef struct Zdata aZdata; +#endif + #ifdef NEED_U_INT32_T typedef unsigned int u_int32_t; /* XXX Hope this works! */ #endif @@ -279,7 +283,9 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */ #define FLAGS_NETINFO 0x200000 #define FLAGS_HYBNOTICE 0x400000 #define FLAGS_QUARANTINE 0x800000 -#define FLAGS_UNOCCUP2 0x1000000 +#ifdef ZIP_LINKS +#define FLAGS_ZIP 0x1000000 +#endif #define FLAGS_UNOCCUP3 0x2000000 #define FLAGS_SHUNNED 0x4000000 #ifdef USE_SSL @@ -383,6 +389,11 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */ #define IsSecure(x) (0) #endif +#ifdef ZIP_LINKS +#define IsZipped(x) ((x)->flags & FLAGS_ZIP) +#define IsZipStart(x) (((x)->flags & FLAGS_ZIP) && ((x)->zip->first == 1)) +#endif + #define IsHybNotice(x) ((x)->flags & FLAGS_HYBNOTICE) #define SetHybNotice(x) ((x)->flags |= FLAGS_HYBNOTICE) #define ClearHybNotice(x) ((x)->flags &= ~FLAGS_HYBNOTICE) @@ -441,6 +452,10 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */ #define ClearHidden(x) ((x)->umodes &= ~UMODE_HIDE) #define ClearHideOper(x) ((x)->umodes &= ~UMODE_HIDEOPER) +#ifdef ZIP_LINKS +#define SetZipped(x) ((x)->flags |= FLAGS_ZIP) +#define ClearZipped(x) ((x)->flags &= ~FLAGS_ZIP) +#endif /* * ProtoCtl options diff --git a/include/zip.h b/include/zip.h index 4a383fae8..25d6d7325 100644 --- a/include/zip.h +++ b/include/zip.h @@ -43,6 +43,7 @@ struct Zdata { char outbuf[ZIP_MAXIMUM]; /* outgoing (unzipped) buffer */ int incount; /* size of inbuf content */ int outcount; /* size of outbuf content */ + int first; /* First message? */ }; #endif /* ZIP_LINKS */ diff --git a/src/cloak.c b/src/cloak.c index 1d70897ed..7fa878c50 100644 --- a/src/cloak.c +++ b/src/cloak.c @@ -146,7 +146,7 @@ static unsigned long crc32_tab[] = { /* Return a 32-bit CRC of the contents of the buffer. */ -unsigned long crc32(const unsigned char *s, unsigned int len) +unsigned long our_crc32(const unsigned char *s, unsigned int len) { unsigned int i; unsigned long crc32val; @@ -197,12 +197,12 @@ char *hidehost(char *rhost) &l[4], &l[5], &l[6], &l[7]); ircsprintf(h3, "%lx:%lx:%lx:%lx", l[0], l[1], l[2], l[3]); - l[0] = crc32(h3, strlen(h3)); + l[0] = our_crc32(h3, strlen(h3)); ircsprintf(h3, "%lx:%lx:%lx:%lx:%lx:%lx:%lx", l[0], l[1], l[2], l[3], l[4], l[5], l[6]); - l[1] = crc32(h3, strlen(h3)); - l[2] = crc32(host, strlen(host)); + l[1] = our_crc32(h3, strlen(h3)); + l[2] = our_crc32(host, strlen(host)); for (i = 0; i <= 2; i++) { #ifdef COMPAT_BETA4_KEYS @@ -237,17 +237,17 @@ char *hidehost(char *rhost) } #ifndef COMPAT_BETA4_KEYS ircsprintf(h3, "%s.%s", h2[0], h2[1]); - l[0] = ((crc32(h3, strlen(h3)) + KEY) ^ KEY2) + KEY3; + l[0] = ((our_crc32(h3, strlen(h3)) + KEY) ^ KEY2) + KEY3; ircsprintf(h3, "%s.%s.%s", h2[0], h2[1], h2[2]); - l[1] = ((KEY2 ^ crc32(h3, strlen(h3))) + KEY3) ^ KEY; - l[4] = crc32(host, strlen(host)); + l[1] = ((KEY2 ^ our_crc32(h3, strlen(h3))) + KEY3) ^ KEY; + l[4] = our_crc32(host, strlen(host)); l[2] = ((l[4] + KEY3) ^ KEY) + KEY2; #else ircsprintf(h3, "%s.%s", h2[0], h2[1]); - l[0] = ((crc32(h3, strlen(h3)) + KEY2) ^ KEY) ^ KEY3; + l[0] = ((our_crc32(h3, strlen(h3)) + KEY2) ^ KEY) ^ KEY3; ircsprintf(h3, "%s.%s.%s", h2[0], h2[1], h2[2]); - l[1] = ((KEY2 + crc32(h3, strlen(h3))) ^ KEY3) ^ KEY; - l[4] = crc32(host, strlen(host)); + l[1] = ((KEY2 + our_crc32(h3, strlen(h3))) ^ KEY3) ^ KEY; + l[4] = our_crc32(host, strlen(host)); l[2] = ((l[4] + KEY) ^ KEY3)^ KEY2; #endif l[2] &= 0x3FFFFFFF; @@ -272,9 +272,9 @@ char *hidehost(char *rhost) } } #ifdef COMPAT_BETA4_KEYS - l[0] = ((crc32(host, strlen(host)) + KEY2) ^ KEY)^ KEY3; + l[0] = ((our_crc32(host, strlen(host)) + KEY2) ^ KEY)^ KEY3; #else - l[0] = ((crc32(host, strlen(host)) ^ KEY2) + KEY) ^ KEY3; + l[0] = ((our_crc32(host, strlen(host)) ^ KEY2) + KEY) ^ KEY3; #endif l[0] &= 0x3FFFFFFF; if (*p) { diff --git a/src/ircd.c b/src/ircd.c index 328620ff4..bec7088dd 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -1025,6 +1025,9 @@ int InitwIRCD(int argc, char *argv[]) #ifdef USE_SSL fprintf(stderr, " using %s\n\n", OPENSSL_VERSION_TEXT); #endif +#ifdef ZIP_LINKS + fprintf(stderr, " using zlib %s\n\n", zlibVersion()); +#endif #endif clear_client_hash_table(); clear_channel_hash_table(); diff --git a/src/list.c b/src/list.c index 4e3a5927e..a89a5bd44 100644 --- a/src/list.c +++ b/src/list.c @@ -149,8 +149,15 @@ aClient *make_client(aClient *from, aClient *servr) void free_client(aClient *cptr) { - if (MyClient(cptr) && cptr->passwd) - MyFree((char *)cptr->passwd); + if (MyClient(cptr)) + { + if (cptr->passwd) + MyFree((char *)cptr->passwd); +#ifdef ZIP_LINKS + if (cptr->zip) + zip_free(cptr); +#endif + } MyFree((char *)cptr); } diff --git a/src/packet.c b/src/packet.c index 34a886adf..a8c8207cd 100644 --- a/src/packet.c +++ b/src/packet.c @@ -49,6 +49,10 @@ int dopacket(aClient *cptr, char *buffer, int length) char *ch1; char *ch2; aClient *acpt = cptr->listener; +#ifdef ZIP_LINKS + int zipped = 0; + int done_unzip = 0; +#endif me.receiveB += length; /* Update bytes received */ cptr->receiveB += length; @@ -73,6 +77,40 @@ int dopacket(aClient *cptr, char *buffer, int length) } ch1 = cptr->buffer + cptr->count; ch2 = buffer; +#ifdef ZIP_LINKS + if (IsZipStart(cptr)) + { + if (*ch2 == '\n' || *ch2 == '\r') + { + ch2++; + length--; + } + cptr->zip->first = 0; + } else { + done_unzip = 1; + } + + if (IsZipped(cptr)) + { + /* uncompressed buffer first */ + zipped = length; + cptr->zip->inbuf[0] = '\0'; /* unnecessary but nicer for debugging */ + cptr->zip->incount = 0; + ch2 = unzip_packet(cptr, ch2, &zipped); + length = zipped; + zipped = 1; + if (length == -1) + return exit_client(cptr, cptr, &me, + "fatal error in unzip_packet(1)"); + } + + /* While there is "stuff" in the compressed input to deal with, + * keep loop parsing it. I have to go through this loop at least once. + * -Dianora + */ + do + { +#endif while (--length >= 0) { char g = (*ch1 = *ch2++); @@ -110,12 +148,63 @@ int dopacket(aClient *cptr, char *buffer, int length) if (cptr->flags & FLAGS_DEADSOCKET) return exit_client(cptr, cptr, &me, "Dead Socket"); +#ifdef ZIP_LINKS + if ((IsZipped(cptr)) && (zipped == 0) && (length > 0)) + { + /* + ** beginning of server connection, the buffer + ** contained PASS/CAPAB/SERVER and is now + ** zipped! + ** Ignore the '\n' that should be here. + */ + /* Checked RFC1950: \r or \n can't start a + ** zlib stream -orabidoo + */ + zipped = length; + if (zipped > 0 && (*ch2 == '\n' || *ch2 == '\r')) + { + ch2++; + zipped--; + } + cptr->zip->first = 0; + ch2 = unzip_packet(cptr, ch2, &zipped); + length = zipped; + zipped = 1; + if (length == -1) + return exit_client(cptr, cptr, &me, + "fatal error in unzip_packet(2)"); + } +#endif ch1 = cptr->buffer; } else if (ch1 < cptr->buffer + (sizeof(cptr->buffer) - 1)) ch1++; /* There is always room for the null */ } +#ifdef ZIP_LINKS + /* Now see if anything is left uncompressed in the input + * If so, uncompress it and continue to parse + * -Dianora + */ + if ((IsZipped(cptr)) && cptr->zip->incount) + { + /* This call simply finishes unzipping whats left + * second parameter is not used. -Dianora + */ + ch2 = unzip_packet(cptr, (char *)NULL, &zipped); + length = zipped; + zipped = 1; + if (length == -1) + return exit_client(cptr, cptr, &me, + "fatal error in unzip_packet(3)"); + ch1 = ch2 + length; + done_unzip = 0; + } else { + done_unzip = 1; + } + + } while(!done_unzip); +#endif cptr->count = ch1 - cptr->buffer; return 0; } diff --git a/src/random.c b/src/random.c index a2f927ddc..f61dfb2bf 100644 --- a/src/random.c +++ b/src/random.c @@ -98,7 +98,7 @@ void add_entropy_configfile(struct stat st, char *buf) { entropy_cfgsize = (entropy_cfgsize << 4) ^ st.st_size; entropy_cfgmtime = (entropy_cfgmtime << 4) ^ st.st_mtime; - entropy_cfgcrc = entropy_cfgcrc ^ (unsigned int)crc32(buf, strlen(buf)); + entropy_cfgcrc = entropy_cfgcrc ^ (unsigned int)our_crc32(buf, strlen(buf)); Debug((DEBUG_INFO, "add_entropy_configfile: cfgsize: %u", entropy_cfgsize)); Debug((DEBUG_INFO, "add_entropy_configfile: cfgmtime: %u", (unsigned int)entropy_cfgmtime)); diff --git a/src/s_bsd.c b/src/s_bsd.c index a05637523..f0e699317 100644 --- a/src/s_bsd.c +++ b/src/s_bsd.c @@ -118,7 +118,7 @@ void set_sock_opts(int, aClient *); #else void set_sock_opts(int, aClient *); #endif -static char readbuf[8192]; +static char readbuf[READBUF_SIZE]; char zlinebuf[BUFSIZE]; extern char *version; extern ircstats IRCstats; @@ -1666,7 +1666,11 @@ int read_message(time_t delay, fdlist *listp) FD_SET(cptr->fd, &read_set); } if ((cptr->fd >= 0) && (DBufLength(&cptr->sendQ) || IsConnecting(cptr) || - (DoList(cptr) && IsSendable(cptr)))) + (DoList(cptr) && IsSendable(cptr)) +#ifdef ZIP_LINKS + || ((IsZipped(cptr)) && (cptr->zip->outcount > 0)) +#endif + )) { FD_SET(cptr->fd, &write_set); } @@ -2108,6 +2112,8 @@ int read_message(time_t delay, fdlist *listp) res_pfd = pfd; } +/* FIXME: no ZIP link handling here, but this code doesnt work anyway -- Syzop */ + if (me.socksfd >= 0) { PFD_SETR(me.socksfd); diff --git a/src/s_conf.c b/src/s_conf.c index f5b69b0b3..4c2845817 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -4764,7 +4764,7 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce) tempiConf.network.key3 = ircabs(atol(cep->ce_entries->ce_next->ce_next->ce_varname)); ircsprintf(temp, "%li.%li.%li", tempiConf.network.key, tempiConf.network.key2, tempiConf.network.key3); - tempiConf.network.keycrc = (long) crc32(temp, strlen(temp)); + tempiConf.network.keycrc = (long) our_crc32(temp, strlen(temp)); } else if (!strcmp(cep->ce_varname, "ssl")) { #ifdef USE_SSL diff --git a/src/s_serv.c b/src/s_serv.c index 8a56b39b0..917934ab9 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -516,6 +516,18 @@ CMD_FUNC(m_protoctl) proto, cptr->name)); cptr->proto |= PROTO_SJB64; } + else if (strcmp(s, "ZIP") == 0) + { + if (remove) + { + cptr->proto &= ~PROTO_ZIP; + continue; + } + Debug((DEBUG_ERROR, + "Chose protocol %s for link %s", + proto, cptr->name)); + cptr->proto |= PROTO_ZIP; + } /* * Add other protocol extensions here, with proto * containing the base option, and options containing @@ -832,7 +844,8 @@ CMD_FUNC(m_server) if (aconf->options & CONNECT_QUARANTINE) cptr->flags |= FLAGS_QUARANTINE; /* Start synch now */ - m_server_synch(cptr, numeric, aconf); + if (m_server_synch(cptr, numeric, aconf) == FLUSH_BUFFER) + return FLUSH_BUFFER; } else { @@ -1002,6 +1015,19 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf) serveropts, me.serv->numeric, (me.info[0]) ? (me.info) : "IRCers United"); } +#ifdef ZIP_LINKS + if (aconf->options & CONNECT_ZIP) + { + if (zip_init(cptr) == -1) + { + zip_free(cptr); + sendto_realops("Unable to setup compressed link for %s", get_client_name(cptr, TRUE)); + return exit_client(cptr, cptr, &me, "zip_init() failed"); + } + SetZipped(cptr); + cptr->zip->first = 1; + } +#endif /* Set up server structure */ SetServer(cptr); IRCstats.me_servers++; @@ -1018,17 +1044,39 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf) #ifdef USE_SSL if (IsSecure(cptr)) { - sendto_serv_butone(&me, ":%s SMO o :(\2link\2) Secure link %s -> %s established (%s)", - me.name, me.name, inpath, (char *) ssl_get_cipher((SSL *)cptr->ssl)); - sendto_realops("(\2link\2) Secure link %s -> %s established (%s)", + sendto_serv_butone(&me, ":%s SMO o :(\2link\2) Secure %slink %s -> %s established (%s)", + me.name, +#ifdef ZIP_LINKS + (aconf->options & CONNECT_ZIP) ? "ZIP" : "", +#else + "", +#endif + me.name, inpath, (char *) ssl_get_cipher((SSL *)cptr->ssl)); + sendto_realops("(\2link\2) Secure %slink %s -> %s established (%s)", +#ifdef ZIP_LINKS + (aconf->options & CONNECT_ZIP) ? "ZIP" : "", +#else + "", +#endif me.name, inpath, (char *) ssl_get_cipher((SSL *)cptr->ssl)); } else #endif { - sendto_serv_butone(&me, ":%s SMO o :(\2link\2) Link %s -> %s established", - me.name, me.name, inpath); - sendto_realops("(\2link\2) Link %s -> %s established", + sendto_serv_butone(&me, ":%s SMO o :(\2link\2) %sLink %s -> %s established", + me.name, +#ifdef ZIP_LINKS + (aconf->options & CONNECT_ZIP) ? "ZIP" : "", +#else + "", +#endif + me.name, inpath); + sendto_realops("(\2link\2) %sLink %s -> %s established", +#ifdef ZIP_LINKS + (aconf->options & CONNECT_ZIP) ? "ZIP" : "", +#else + "", +#endif me.name, inpath); } (void)add_to_client_hash_table(cptr->name, cptr); @@ -1397,6 +1445,15 @@ CMD_FUNC(m_netinfo) ("Link %s -> %s is now synced [secs: %li recv: %li.%li sent: %li.%li]", cptr->name, me.name, (TStime() - endsync), sptr->receiveK, sptr->receiveB, sptr->sendK, sptr->sendB); +#ifdef ZIP_LINKS + if ((MyConnect(cptr)) && (IsZipped(cptr)) && cptr->zip->out->total_in) { + sendto_realops + ("Zipstats for link to %s: %01lu, compressed %01lu (%3.1f%%)", + get_client_name(cptr, TRUE), cptr->zip->out->total_in, + cptr->zip->out->total_out, + (100.0*(float)cptr->zip->out->total_out) /(float)cptr->zip->out->total_in); + } +#endif sendto_serv_butone(&me, ":%s SMO o :\2(sync)\2 Link %s -> %s is now synced [secs: %li recv: %li.%li sent: %li.%li]", diff --git a/src/send.c b/src/send.c index 53d242156..82024774d 100644 --- a/src/send.c +++ b/src/send.c @@ -158,7 +158,9 @@ int send_queued(aClient *to) { char *msg; int len, rlen; - +#ifdef ZIP_LINKS + int more = 0; +#endif if (IsBlocked(to)) return -1; /* Can't write to already blocked socket */ @@ -175,6 +177,23 @@ int send_queued(aClient *to) */ return -1; } +#ifdef ZIP_LINKS + /* + ** Here, we must make sure than nothing will be left in to->zip->outbuf + ** This buffer needs to be compressed and sent if all the sendQ is sent + */ + if ((IsZipped(to)) && to->zip->outcount) { + if (DBufLength(&to->sendQ) > 0) { + more = 1; + } else { + msg = zip_buffer(to, NULL, &len, 1); + if (len == -1) + return dead_link(to, "fatal error in zip_buffer()"); + if (!dbuf_put(&to->sendQ, msg, len)) + return dead_link(to, "Buffer allocation error for %s"); + } + } +#endif while (DBufLength(&to->sendQ) > 0) { msg = dbuf_map(&to->sendQ, &len); @@ -190,6 +209,20 @@ int send_queued(aClient *to) SetBlocked(to); break; } +#ifdef ZIP_LINKS + if (DBufLength(&to->sendQ) == 0 && more) { + /* + ** The sendQ is now empty, compress what's left + ** uncompressed and try to send it too + */ + more = 0; + msg = zip_buffer(to, NULL, &len, 1); + if (len == -1) + return dead_link(to, "fatal error in zip_buffer()"); + if (!dbuf_put(&to->sendQ, msg, len)) + return dead_link(to, "Buffer allocation error for %s"); + } +#endif } return (IsDead(to)) ? -1 : 0; @@ -216,7 +249,8 @@ void vsendto_one(aClient *to, char *pattern, va_list vl) void sendbufto_one(aClient *to) { int len; - + char *msg = sendbuf; + Debug((DEBUG_ERROR, "Sending [%s] to %s", sendbuf, to->name)); if (to->from) @@ -265,7 +299,20 @@ void sendbufto_one(aClient *to) return; } +#ifdef ZIP_LINKS + /* + ** data is first stored in to->zip->outbuf until + ** it's big enough to be compressed and stored in the sendq. + ** send_queued is then responsible to never let the sendQ + ** be empty and to->zip->outbuf not empty. + */ + if (IsZipped(to)) + msg = zip_buffer(to, msg, &len, 0); + + if (len && !dbuf_put(&to->sendQ, msg, len)) +#else if (!dbuf_put(&to->sendQ, sendbuf, len)) +#endif { dead_link(to, "Buffer allocation error"); return; diff --git a/src/zip.c b/src/zip.c index cacd98de6..b686e7557 100644 --- a/src/zip.c +++ b/src/zip.c @@ -50,7 +50,7 @@ ** (cptr->zip->inbuf should never hold more than ONE compression block. ** The biggest block allowed for compression is ZIP_MAXIMUM bytes) */ -#define ZIP_BUFFER_SIZE (ZIP_MAXIMUM + BUFSIZE) +#define ZIP_BUFFER_SIZE (ZIP_MAXIMUM + READBUF_SIZE) /* ** size of the buffer where zlib puts compressed data @@ -86,6 +86,7 @@ int zip_init(aClient *cptr) cptr->zip->outcount = 0; cptr->zip->in = (z_stream *) MyMalloc(sizeof(z_stream)); + bzero(cptr->zip->in, sizeof(z_stream)); /* Just to be sure -- Syzop */ cptr->zip->in->total_in = 0; cptr->zip->in->total_out = 0; cptr->zip->in->zalloc = (alloc_func)0; @@ -98,6 +99,7 @@ int zip_init(aClient *cptr) } cptr->zip->out = (z_stream *) MyMalloc(sizeof(z_stream)); + bzero(cptr->zip->out, sizeof(z_stream)); /* Just to be sure -- Syzop */ cptr->zip->out->total_in = 0; cptr->zip->out->total_out = 0; cptr->zip->out->zalloc = (alloc_func)0; @@ -114,7 +116,7 @@ int zip_init(aClient *cptr) */ void zip_free(aClient *cptr) { - cptr->flags2 &= ~FLAGS2_ZIP; + SetZipped(cptr); if (cptr->zip) { if (cptr->zip->in) @@ -151,7 +153,7 @@ char *unzip_packet(aClient *cptr, char *buffer, int *length) */ memcpy((void *)unzipbuf,(void *)cptr->zip->inbuf,cptr->zip->incount); zin->avail_out = UNZIP_BUFFER_SIZE - cptr->zip->incount; - zin->next_out = unzipbuf + cptr->zip->incount; + zin->next_out = (Bytef *) (unzipbuf + cptr->zip->incount); cptr->zip->incount = 0; cptr->zip->inbuf[0] = '\0'; /* again unnecessary but nice for debugger */ } @@ -167,9 +169,9 @@ char *unzip_packet(aClient *cptr, char *buffer, int *length) *length = -1; return((char *)NULL); } - zin->next_in = buffer; + zin->next_in = (Bytef *) buffer; zin->avail_in = *length; - zin->next_out = unzipbuf; + zin->next_out = (Bytef *) unzipbuf; zin->avail_out = UNZIP_BUFFER_SIZE; } @@ -216,7 +218,7 @@ char *unzip_packet(aClient *cptr, char *buffer, int *length) * the bottom of the unzip buffer. -db */ - for(p = zin->next_out;p >= unzipbuf;) + for(p = (char *) zin->next_out;p >= unzipbuf;) { if((*p == '\r') || (*p == '\n')) break; @@ -266,10 +268,10 @@ char *unzip_packet(aClient *cptr, char *buffer, int *length) break; case Z_DATA_ERROR: /* the buffer might not be compressed.. */ - if ((IsCapable(cptr, CAP_ZIP)) && !strncmp("ERROR ", buffer, 6)) + if (!strncmp("ERROR ", buffer, 6)) { - cptr->flags2 &= ~FLAGS2_ZIP; - cptr->caps &= ~CAP_ZIP; + cptr->zip->first = 0; + ClearZipped(cptr); /* * This is not sane at all. But if other server * has sent an error now, it is probably closing @@ -277,7 +279,9 @@ char *unzip_packet(aClient *cptr, char *buffer, int *length) */ return buffer; } - + /* Let's be nice and give them a hint ;) -- Syzop */ + sendto_realops("inflate() error: * Are you perhaps linking zipped with non-zipped? *"); + sendto_realops("Hint: link::options::zip should be the same at both sides (either both disabled or both enabled)"); /* no break */ default: /* error ! */ @@ -310,20 +314,25 @@ char *zip_buffer(aClient *cptr, char *buffer, int *length, int flush) if (buffer) { /* concatenate buffer in cptr->zip->outbuf */ - memcpy((void *)cptr->zip->outbuf + cptr->zip->outcount, (void *)buffer, + memcpy((void *)(cptr->zip->outbuf + cptr->zip->outcount), (void *)buffer, *length ); cptr->zip->outcount += *length; } *length = 0; +#if 0 if (!flush && ((cptr->zip->outcount < ZIP_MINIMUM) || ((cptr->zip->outcount < (ZIP_MAXIMUM - BUFSIZE)) && CBurst(cptr)))) + /* Implement this? more efficient? or not? -- Syzop */ +#else + if (!flush && (cptr->zip->outcount < ZIP_MINIMUM)) +#endif return((char *)NULL); - zout->next_in = cptr->zip->outbuf; + zout->next_in = (Bytef *) cptr->zip->outbuf; zout->avail_in = cptr->zip->outcount; - zout->next_out = zipbuf; + zout->next_out = (Bytef *) zipbuf; zout->avail_out = ZIP_BUFFER_SIZE; switch (r = deflate(zout, Z_PARTIAL_FLUSH))