Michael Schierl schrieb:
> 
> Matthew Toseland schrieb:
>
> but it seems to be a bit of work to replace all that
> n.randSource.nextLong() refs by a synchronized method of Node/Core...
> (okay, full text search finds 13 files, but what if it is not n or if
> the call is separated into two?

looke at the source more thorougly and found lotsa places where the
RandomSource is handed from one class to another, stored in properties
and so on. Seems to be impossible to change that.

So i wrote a small "wrapper" RandomSource class and wrapped Scotts
RandomSource implementation:

#v+
--- fn-cvs/src/freenet/Core.java        2003-03-12 00:57:30.000000000
+0100
+++ fn-local/src/freenet/Core.java      2003-04-02 10:54:26.000000000
+0200
@@ -140,8 +140,9 @@
     public static RandomSource randSource;
     static {
         randSource =
-            new Yarrow((new File("/dev/urandom").exists()
-                        ? "/dev/urandom" : "prng.seed"), "SHA1",
"Rijndael");
+            new SynchronizedRandomSourceWrapper
+            (new Yarrow((new File("/dev/urandom").exists()
+                         ? "/dev/urandom" : "prng.seed"), "SHA1",
"Rijndael"));

     }

     /** The object that logs events */
#v-

if someone with cvs write access could check this into the unstable
branch perhaps? (yes, due to the delegation it might slow Freenet down -
but i did not find any better solution to synchronize all calls to the
RandomSource)

If someone has a better solution, tell me.

mihi

PS: My hunt servlet did not find any heisenbugged IDs afterwards -
however, this does not guarantee that all heisenbugs are away now...
package freenet.crypt;

/** a wrapper class that delegates all calls to another
 * RandomSource. All calls are synchronized on this wrapper object.
 *
 * do *not* call setSeed on this object!
 *
 * @author mihi
 */
public class SynchronizedRandomSourceWrapper extends RandomSource {

    /** the object where all calls are delegated to */
    private RandomSource rnd;
    
    public SynchronizedRandomSourceWrapper(RandomSource rnd) {
        super(); // this line calls setSeed()!
        this.rnd=rnd;
    }

//      synchronized public void setSeed(long seed) {
//         if (rnd==null) {
//             super.setSeed(seed);
//         } else {
//             rnd.setSeed(seed);
//         }
//      }

//      protected synchronized int next(int bits) {
//         return rnd.next(bits);
//      }

    public synchronized void nextBytes(byte[] bytes) {
        rnd.nextBytes(bytes);
    }
    public synchronized int nextInt() {
        return rnd.nextInt();
    }
    
    public synchronized int nextInt(int n) {
        return rnd.nextInt(n);
    }

    public synchronized long nextLong() {
        long l = rnd.nextLong();
        // FIXME: log heisenbugs here...?
        return l;
    }

    public synchronized boolean nextBoolean() {
        return rnd.nextBoolean();
    }

    public synchronized float nextFloat() {
        return rnd.nextFloat();
    }

    public synchronized double nextDouble() {
        return rnd.nextDouble();
    }


    synchronized public double nextGaussian() {
        return rnd.nextGaussian();
    }

    public synchronized float nextFullFloat() {
        return rnd.nextFullFloat();
    }

    public synchronized double nextFullDouble() {
        return rnd.nextFullDouble();
    }

    public synchronized int acceptEntropy(EntropySource source, long data,
                                          int entropyGuess) {
        return rnd.acceptEntropy(source, data, entropyGuess);
    }
    public synchronized int acceptTimerEntropy(EntropySource timer) {
        return rnd.acceptTimerEntropy(timer);
    }

    public synchronized void waitForEntropy(int bits) {
        rnd.waitForEntropy(bits);
    }

    public synchronized void close() {
        rnd.close();
    }
}

Reply via email to