public void update() { logMINOR = Logger.shouldLog(Logger.MINOR, this); if (logMINOR) Logger.minor(this, "update()"); if (!checkIPUpdated()) return; // We'll broadcast the new physical.udp entry to our connected peers via a differential node // reference // We'll err on the side of caution and not update our peer to an empty physical.udp entry using // a differential node reference SimpleFieldSet nfs = crypto.exportPublicFieldSet(false, false, true); String[] entries = nfs.getAll("physical.udp"); if (entries != null) { SimpleFieldSet fs = new SimpleFieldSet(true); fs.putOverwrite("physical.udp", entries); if (logMINOR) Logger.minor(this, darknetOpennetString + " ref's physical.udp is '" + fs.toString() + "'"); node.peers.locallyBroadcastDiffNodeRef(fs, !crypto.isOpennet, crypto.isOpennet); } else { if (logMINOR) Logger.minor(this, darknetOpennetString + " ref's physical.udp is null"); } // Proceed with inserting the ARK if (logMINOR) Logger.minor(this, "Inserting " + darknetOpennetString + " ARK because peers list changed"); if (inserter != null) { // Already inserting. // Re-insert after finished. synchronized (this) { shouldInsert = true; } return; } // Otherwise need to start an insert if (node.noConnectedPeers()) { // Can't start an insert yet synchronized (this) { shouldInsert = true; } return; } startInserter(); }
private void startInserter() { if (!canStart) { if (logMINOR) Logger.minor(this, darknetOpennetString + " ARK inserter can't start yet"); return; } if (logMINOR) Logger.minor(this, "starting " + darknetOpennetString + " ARK inserter"); SimpleFieldSet fs = crypto.exportPublicFieldSet(false, false, true); // Remove some unnecessary fields that only cause collisions. // Delete entire ark.* field for now. Changing this and automatically moving to the new may be // supported in future. fs.removeSubset("ark"); fs.removeValue("location"); fs.removeValue("sig"); // fs.remove("version"); - keep version because of its significance in reconnection String s = fs.toString(); byte[] buf; try { buf = s.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new Error("Impossible: JVM doesn't support UTF-8: " + e, e); } Bucket b = new SimpleReadOnlyArrayBucket(buf); long number = crypto.myARKNumber; InsertableClientSSK ark = crypto.myARK; FreenetURI uri = ark.getInsertURI().setKeyType("USK").setSuggestedEdition(number); if (logMINOR) Logger.minor( this, "Inserting " + darknetOpennetString + " ARK: " + uri + " contents:\n" + s); inserter = new ClientPutter( this, b, uri, new ClientMetadata("text/plain") /* it won't quite fit in an SSK anyway */, node.clientCore.makeClient((short) 0, true).getInsertContext(true), RequestStarter.INTERACTIVE_PRIORITY_CLASS, false, false, this, null, null, false); try { node.clientCore.clientContext.start(inserter, false); synchronized (this) { if (fs.get("physical.udp") == null) lastInsertedPeers = null; else { try { String[] all = fs.getAll("physical.udp"); Peer[] peers = new Peer[all.length]; for (int i = 0; i < all.length; i++) peers[i] = new Peer(all[i], false); lastInsertedPeers = peers; } catch (PeerParseException e1) { Logger.error( this, "Error parsing own " + darknetOpennetString + " ref: " + e1 + " : " + fs.get("physical.udp"), e1); } catch (UnknownHostException e1) { Logger.error( this, "Error parsing own " + darknetOpennetString + " ref: " + e1 + " : " + fs.get("physical.udp"), e1); } } } } catch (InsertException e) { onFailure(e, inserter, null); } catch (DatabaseDisabledException e) { // Impossible } }
/** * Create a ClientGet from a request serialized to a SimpleFieldSet. Can throw, and does minimal * verification, as is dealing with data supposedly serialized out by the node. * * @throws IOException * @throws FetchException */ public ClientGet(SimpleFieldSet fs, FCPClient client2, FCPServer server) throws IOException, FetchException { super(fs, client2); returnType = ClientGetMessage.parseValidReturnType(fs.get("ReturnType")); String f = fs.get("Filename"); if (f != null) targetFile = new File(f); else targetFile = null; f = fs.get("TempFilename"); if (f != null) tempFile = new File(f); else tempFile = null; boolean ignoreDS = Fields.stringToBool(fs.get("IgnoreDS"), false); boolean dsOnly = Fields.stringToBool(fs.get("DSOnly"), false); int maxRetries = Integer.parseInt(fs.get("MaxRetries")); fctx = new FetchContext(server.defaultFetchContext, FetchContext.IDENTICAL_MASK, false, null); fctx.eventProducer.addEventListener(this); // ignoreDS fctx.localRequestOnly = dsOnly; fctx.ignoreStore = ignoreDS; fctx.maxNonSplitfileRetries = maxRetries; fctx.maxSplitfileBlockRetries = maxRetries; binaryBlob = Fields.stringToBool(fs.get("BinaryBlob"), false); succeeded = Fields.stringToBool(fs.get("Succeeded"), false); if (finished) { if (succeeded) { foundDataLength = Long.parseLong(fs.get("FoundDataLength")); foundDataMimeType = fs.get("FoundDataMimeType"); SimpleFieldSet fs1 = fs.subset("PostFetchProtocolError"); if (fs1 != null) postFetchProtocolErrorMessage = new ProtocolErrorMessage(fs1); } else { getFailedMessage = new GetFailedMessage(fs.subset("GetFailed"), false); } } Bucket ret = null; if (returnType == ClientGetMessage.RETURN_TYPE_DISK) { if (succeeded) { ret = new FileBucket(targetFile, false, true, false, false, false); } else { ret = new FileBucket(tempFile, false, true, false, false, false); } } else if (returnType == ClientGetMessage.RETURN_TYPE_NONE) { ret = new NullBucket(); } else if (returnType == ClientGetMessage.RETURN_TYPE_DIRECT) { try { ret = SerializableToFieldSetBucketUtil.create( fs.subset("ReturnBucket"), server.core.random, server.core.persistentTempBucketFactory); if (ret == null) throw new CannotCreateFromFieldSetException("ret == null"); } catch (CannotCreateFromFieldSetException e) { Logger.error(this, "Cannot read: " + this + " : " + e, e); try { // Create a new temp bucket if (persistenceType == PERSIST_FOREVER) ret = server.core.persistentTempBucketFactory.makeBucket(fctx.maxOutputLength); else ret = server.core.tempBucketFactory.makeBucket(fctx.maxOutputLength); } catch (IOException e1) { Logger.error(this, "Cannot create bucket for temp storage: " + e, e); getter = null; returnBucket = null; throw new FetchException(FetchException.BUCKET_ERROR, e); } } } else { throw new IllegalArgumentException(); } if (succeeded) { if (foundDataLength < ret.size()) { Logger.error(this, "Failing " + identifier + " because lost data"); succeeded = false; } } if (ret == null) Logger.error( this, "Impossible: ret = null in SFS constructor for " + this, new Exception("debug")); returnBucket = ret; String[] allowed = fs.getAll("AllowedMIMETypes"); if (allowed != null) { fctx.allowedMIMETypes = new HashSet<String>(); for (String a : allowed) fctx.allowedMIMETypes.add(a); } getter = new ClientGetter( this, uri, fctx, priorityClass, lowLevelClient, binaryBlob ? new NullBucket() : returnBucket, binaryBlob ? returnBucket : null); if (finished && succeeded) allDataPending = new AllDataMessage( returnBucket, identifier, global, startupTime, completionTime, this.foundDataMimeType); }