Index: ../ircu2.10.06/todo.jcea =================================================================== RCS file: /usr/local/cvsroot/ircu2.10.06/todo.jcea,v retrieving revision 1.3 retrieving revision 1.6 diff -c -r1.3 -r1.6 *** ../ircu2.10.06/todo.jcea 1999/10/08 11:42:38 1.3 --- ../ircu2.10.06/todo.jcea 1999/10/08 15:10:47 1.6 *************** *** 8,16 **** Ojo con el tema de las compactaciones en las bases de datos no residentes, asi como el calculo de su HASH. - 08/Oct/99 HECHO - Recalcular HASH cuando se compacta una BDD. - 08/Oct/99 ! Guardar en disco los HASH de las BDD, como ! proteccion ante corrupciones. --- 8,21 ---- Ojo con el tema de las compactaciones en las bases de datos no residentes, asi como el calculo de su HASH. 08/Oct/99 ! Cuando un servidor detecta que una de sus BDD ! esta corrupta, solicita una copia nueva a TODOS ! sus enlaces. Si es un HUB, ello supone: ! ! * Que recibira actualizaciones por todos sus enlaces ! * Que enviara dichas actualizaciones por todos los enlaces ! ! Esto es un consumo de ancho de banda y CPU importante, ! aunque solo se produce en los HUBs con BDD corrupta. ! Index: ../ircu2.10.06/include/struct.h =================================================================== RCS file: /usr/local/cvsroot/ircu2.10.06/include/struct.h,v retrieving revision 1.3 retrieving revision 1.4 diff -c -r1.3 -r1.4 *** ../ircu2.10.06/include/struct.h 1999/10/06 21:57:25 1.3 --- ../ircu2.10.06/include/struct.h 1999/10/08 11:57:19 1.4 *************** *** 195,200 **** --- 195,201 ---- #define DBH_BOTSDB 'B' #define DBH_VIRTUALDB 'V' #define ESNET_BDD 'a' + #define ESNET_BDD_END 'z' #define ESNET_NICKDB 'n' /* Para las features del Virtual CHaN */ Index: ../ircu2.10.06/ircd/s_debug.c =================================================================== RCS file: /usr/local/cvsroot/ircu2.10.06/ircd/s_debug.c,v retrieving revision 1.13 retrieving revision 1.14 diff -c -r1.13 -r1.14 *** ../ircu2.10.06/ircd/s_debug.c 1999/10/08 11:42:44 1.13 --- ../ircu2.10.06/ircd/s_debug.c 1999/10/08 11:49:20 1.14 *************** *** 191,197 **** '-', #endif #endif ! 'D','B','2','2', #ifdef DB_ESNET '+', #else --- 191,197 ---- '-', #endif #endif ! 'D','B','2','3', #ifdef DB_ESNET '+', #else Index: ../ircu2.10.06/ircd/s_serv.c =================================================================== RCS file: /usr/local/cvsroot/ircu2.10.06/ircd/s_serv.c,v retrieving revision 1.17 retrieving revision 1.19 diff -c -r1.17 -r1.19 *** ../ircu2.10.06/ircd/s_serv.c 1999/10/08 11:42:44 1.17 --- ../ircu2.10.06/ircd/s_serv.c 1999/10/08 15:10:47 1.19 *************** *** 1215,1222 **** */ memset(buffer,0,sizeof(buffer)); strncpy((char *)buffer,registro,sizeof(buffer)-1); - while((p2=strchr((char *)buffer,'\r'))) *p2='\0'; while((p2=strchr((char *)buffer,'\n'))) *p2='\0'; k[0]=k[1]=0; x[0]=tabla_hash_hi[que_bdd]; x[1]=tabla_hash_lo[que_bdd]; --- 1215,1222 ---- */ memset(buffer,0,sizeof(buffer)); strncpy((char *)buffer,registro,sizeof(buffer)-1); while((p2=strchr((char *)buffer,'\n'))) *p2='\0'; + while((p2=strchr((char *)buffer,'\r'))) *p2='\0'; k[0]=k[1]=0; x[0]=tabla_hash_hi[que_bdd]; x[1]=tabla_hash_lo[que_bdd]; *************** *** 1572,1577 **** --- 1572,1600 ---- } /* + ** lee_hash + */ + void lee_hash(char que_bdd,unsigned long *hi,unsigned long *lo) { + char path[1024]; + char c; + int db_file; + + sprintf_irc(path,"%s/hashes",DBPATH); + alarm(3); + db_file=open(path,O_RDONLY); + lseek(db_file,15*(que_bdd-ESNET_BDD)+2,SEEK_SET); + read(db_file,path,12); + close(db_file); + alarm(0); + path[12]='\0'; + c=path[6]; + path[6]='\0'; + *hi=base64toint(path); + path[6]=c; + *lo=base64toint(path+6); + } + + /* * db_alta * * Da de alta una entrada en la base de datos en memoria *************** *** 1580,1591 **** * modificado para usar las hash con funciones dbh_* * 1999/06/30 savage@apostols.org */ ! void db_alta(char *registro,char que_bdd) { char *p0, *p1, *p2, *p3, *p4; actualiza_hash(registro,que_bdd); ! almacena_hash(que_bdd); p0=strtok(registro," "); /* serie */ p1=strtok(NULL, " "); /* destino */ --- 1603,1615 ---- * modificado para usar las hash con funciones dbh_* * 1999/06/30 savage@apostols.org */ ! void db_alta(char *registro,char que_bdd,int guarda_hash) { char *p0, *p1, *p2, *p3, *p4; actualiza_hash(registro,que_bdd); ! ! if(guarda_hash) almacena_hash(que_bdd); p0=strtok(registro," "); /* serie */ p1=strtok(NULL, " "); /* destino */ *************** *** 1681,1688 **** /* ** Actualizamos HASH */ ! if((*p=='\n')||(*p=='\r')) actualiza_hash(lectura,que_bdd); ! else { /* Estamos al final y no hay retorno de carro */ memcpy(path,lectura,p-lectura); path[p-lectura]='\0'; actualiza_hash(path,que_bdd); --- 1705,1716 ---- /* ** Actualizamos HASH */ ! if((*p=='\n')||(*p=='\r')) { ! c=*p; ! *p='\0'; ! actualiza_hash(lectura,que_bdd); ! *p=c; ! } else { /* Estamos al final y no hay retorno de carro */ memcpy(path,lectura,p-lectura); path[p-lectura]='\0'; actualiza_hash(path,que_bdd); *************** *** 1713,1747 **** } /* - * initdb - * - * Lee la base de datos de disco - * - */ - void initdb(void) - { - char buf[1024]; - int handle; - - tabla_residente[ESNET_NICKDB]=1; - tabla_serie[ESNET_NICKDB]=0; - tabla_cuantos[ESNET_NICKDB]=0; - - tabla_hash_hi[ESNET_NICKDB]=0; - tabla_hash_lo[ESNET_NICKDB]=0; - - if(!(handle=abrir_db(0,buf,ESNET_NICKDB))) return; - do { - /* db_alta modifica la cadena */ - db_alta(buf,ESNET_NICKDB); - } while(leer_db(handle,buf)!=-1); - - dbh_eliminar_borrados(ESNET_NICKDB); - - return; - } - - /* * borrar_db * * Borra la base de datos en memoria (modificado para uso de hash) --- 1741,1746 ---- *************** *** 1752,1758 **** { int i; struct dbh_reg *reg; ! for(i=0;inext) reg->borrado=1; --- 1751,1757 ---- { int i; struct dbh_reg *reg; ! for(i=0;inext) reg->borrado=1; *************** *** 1766,1771 **** --- 1765,1824 ---- } /* + * initdb + * + * Lee la base de datos de disco + * + */ + void initdb(void) + { + unsigned long hi,lo; + char buf[1024]; + char path[1024]; + int db_file; + Dlink *lp; + + tabla_residente[ESNET_NICKDB]=1; + tabla_serie[ESNET_NICKDB]=0; + tabla_cuantos[ESNET_NICKDB]=0; + + tabla_hash_hi[ESNET_NICKDB]=0; + tabla_hash_lo[ESNET_NICKDB]=0; + + if(!(db_file=abrir_db(0,buf,ESNET_NICKDB))) return; + do { + /* db_alta modifica la cadena */ + db_alta(buf,ESNET_NICKDB,0); + } while(leer_db(db_file,buf)!=-1); + + dbh_eliminar_borrados(ESNET_NICKDB); + + /* + ** Ahora comprueba que el HASH de la BDD + ** cargada se corresponda con el HASH almacenado + */ + lee_hash(ESNET_NICKDB,&hi,&lo); + if((tabla_hash_hi[ESNET_NICKDB]!=hi) || + (tabla_hash_lo[ESNET_NICKDB]!=lo)) { + sendto_ops("ATENCION - Base de Datos " + "'%c' aparentemente corrupta. Borrando...",ESNET_NICKDB); + borrar_db(ESNET_NICKDB); + sprintf_irc(path,"%s/tabla.%c",DBPATH,ESNET_NICKDB); + alarm(3); + db_file=open(path,O_TRUNC,S_IRUSR | S_IWUSR); + close(db_file); + alarm(0); + sendto_ops("Solicitando actualizacion BDD '%c' " + "a los nodos vecinos.",ESNET_NICKDB); + for(lp = me.serv->down; lp; lp = lp->next) { + sendto_one(lp->value.cptr,"%s DB %s 0 J %lu %c", + NumServ(&me),lp->value.cptr->name,tabla_serie[ESNET_NICKDB],ESNET_NICKDB); + } + } + almacena_hash(ESNET_NICKDB); + } + + /* * reload_db * * Recarga la base de datos de disco, liberando la memoria *************** *** 1773,1781 **** */ void reload_db(void) { ! borrar_db(ESNET_NICKDB); ! initdb(); ! sendto_ops("Releyendo la base de datos. Ultimo registro: %lu",tabla_serie[ESNET_NICKDB]); } --- 1826,1840 ---- */ void reload_db(void) { ! char buf[16]; ! ! sendto_ops("Releyendo Bases de Datos..."); ! borrar_db(ESNET_NICKDB); ! initdb(); ! inttobase64(buf,tabla_hash_hi[ESNET_NICKDB],6); ! inttobase64(buf+6,tabla_hash_lo[ESNET_NICKDB],6); ! sendto_ops("DB: '%c'. Ultimo registro: %lu. HASH: %s", ! ESNET_NICKDB,tabla_serie[ESNET_NICKDB],buf); } *************** *** 1829,1835 **** --- 1888,1910 ---- sptr->serv->esnet_db|=mascara_bdd; return 0; break; + } else if((sptr->serv->esnet_db)&mascara_bdd) { + /* + ** Teniamos el grifo abierto, y ahora + ** nos esta pidiendo registros antiguos. + ** Eso SOLO ocurre si ha detectado que su + ** copia local de la BDD esta corrupta. + */ + sptr->serv->esnet_db&=~mascara_bdd; + /* + ** Borramos su BDD porque es posible + ** que le hayamos enviado mas registros. + ** Es preferible empezar desde cero. + */ + sendto_one(sptr,"%s DB %s 0 D BDD_CORRUPTA %c", + NumServ(&me),sptr->name,que_bdd); } + db_file=abrir_db(db,db_buf,que_bdd); if(db_file==0) return 0; /* Problemas con la DB */ do { *************** *** 1900,1913 **** return 0; break; ! case 'E': case 'R': - /* - ** Ojo bug de lastNNServer - ** Aqui no ataca porque normalmente - ** este nodo NUNCA sera el destinatario - ** de estas respuestas. - */ if((acptr=find_match_server(parv[1]))&&(!IsMe(acptr))) sendto_one(acptr,"%s DB %s 0 %c %s %c",NumServ(sptr), acptr->name,*parv[3],parv[4],que_bdd); --- 1975,1982 ---- return 0; break; ! case 'E': /* Podemos ser destinatarios si el otro estaba corrupto */ case 'R': if((acptr=find_match_server(parv[1]))&&(!IsMe(acptr))) sendto_one(acptr,"%s DB %s 0 %c %s %c",NumServ(sptr), acptr->name,*parv[3],parv[4],que_bdd); *************** *** 1980,1986 **** sprintf_irc(db_buf,"%lu %s %s %s %s\n",db,parv[1],parv[3],parv[4],parv[5]); strcpy(db_buf2,db_buf); /* db_alta modifica la cadena */ ! if(strcmp(parv[4],"*")) db_alta(db_buf2,que_bdd); /* CheckPoint */ alarm(3); if(strcmp(parv[4],"*")) write(db_file,db_buf,strlen(db_buf)); /* CheckPoint */ --- 2049,2055 ---- sprintf_irc(db_buf,"%lu %s %s %s %s\n",db,parv[1],parv[3],parv[4],parv[5]); strcpy(db_buf2,db_buf); /* db_alta modifica la cadena */ ! if(strcmp(parv[4],"*")) db_alta(db_buf2,que_bdd,!0); /* CheckPoint */ alarm(3); if(strcmp(parv[4],"*")) write(db_file,db_buf,strlen(db_buf)); /* CheckPoint */