* Naming services, addressbook, susidns:

- Fix search capability
    - Fix result count and view within results
    - Fix published address book
    - Fix ngettext
    - Cache size
    - Fix 0-9 filter
    - Addressbook updates via API, except for published
This commit is contained in:
zzz
2011-03-15 21:52:48 +00:00
parent 8b737b4adb
commit 12c5b9c21c
7 changed files with 338 additions and 76 deletions

View File

@ -166,10 +166,10 @@ class AddressBook {
private static final int MAX_DEST_LENGTH = MIN_DEST_LENGTH + 100; // longer than any known cert type for now
/**
* Do basic validation of the hostname and dest
* Do basic validation of the hostname
* hostname was already converted to lower case by ConfigParser.parse()
*/
private static boolean valid(String host, String dest) {
public static boolean isValidKey(String host) {
return
host.endsWith(".i2p") &&
host.length() > 4 &&
@ -193,8 +193,15 @@ class AddressBook {
(! host.equals("console.i2p")) &&
(! host.endsWith(".proxy.i2p")) &&
(! host.endsWith(".router.i2p")) &&
(! host.endsWith(".console.i2p")) &&
(! host.endsWith(".console.i2p"))
;
}
/**
* Do basic validation of the b64 dest, without bothering to instantiate it
*/
private static boolean isValidDest(String dest) {
return
// null cert ends with AAAA but other zero-length certs would be AA
((dest.length() == MIN_DEST_LENGTH && dest.endsWith("AA")) ||
(dest.length() > MIN_DEST_LENGTH && dest.length() <= MAX_DEST_LENGTH)) &&
@ -221,7 +228,7 @@ class AddressBook {
String otherKey = entry.getKey();
String otherValue = entry.getValue();
if (valid(otherKey, otherValue)) {
if (isValidKey(otherKey) && isValidDest(otherValue)) {
if (this.addresses.containsKey(otherKey) && !overwrite) {
if (!this.addresses.get(otherKey).equals(otherValue)
&& log != null) {

View File

@ -29,6 +29,10 @@ import java.util.List;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.client.naming.NamingService;
import net.i2p.client.naming.SingleFileNamingService;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.SecureDirectory;
/**
@ -55,6 +59,7 @@ public class Daemon {
* @param published
* The published AddressBook. This address book is published on
* the user's eepsite so that others may subscribe to it.
* If non-null, overwrite with the new addressbook.
* @param subscriptions
* A SubscriptionList listing the remote address books to update
* from.
@ -75,6 +80,71 @@ public class Daemon {
subscriptions.write();
}
/**
* Update the router and published address books using remote data from the
* subscribed address books listed in subscriptions.
*
* @param router
* The router AddressBook. This is the address book read by
* client applications.
* @param published
* The published AddressBook. This address book is published on
* the user's eepsite so that others may subscribe to it.
* If non-null, overwrite with the new addressbook.
* @param subscriptions
* A SubscriptionList listing the remote address books to update
* from.
* @param log
* The log to write changes and conflicts to.
* @since 0.8.6
*/
public static void update(NamingService router, File published, SubscriptionList subscriptions, Log log) {
NamingService publishedNS = null;
Iterator<AddressBook> iter = subscriptions.iterator();
while (iter.hasNext()) {
// yes, the EepGet fetch() is done in next()
AddressBook sub = iter.next();
for (Map.Entry<String, String> entry : sub.getAddresses().entrySet()) {
String key = entry.getKey();
Destination oldDest = router.lookup(key);
try {
if (oldDest == null) {
if (AddressBook.isValidKey(key)) {
Destination dest = new Destination(entry.getValue());
boolean success = router.put(key, dest);
if (log != null) {
if (success)
log.append("New address " + key +
" added to address book. From: " + sub.getLocation());
else
log.append("Save to naming service " + router + " failed for new key " + key);
}
// now update the published addressbook
if (published != null) {
if (publishedNS == null)
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
success = publishedNS.putIfAbsent(key, dest);
if (!success)
log.append("Save to published addressbook " + published.getAbsolutePath() + " failed for new key " + key);
}
} else if (log != null) {
log.append("Bad hostname " + key + " from "
+ sub.getLocation());
}
} else if (!oldDest.toBase64().equals(entry.getValue()) && log != null) {
log.append("Conflict for " + key + " from "
+ sub.getLocation()
+ ". Destination in remote address book is "
+ entry.getValue());
}
} catch (DataFormatException dfe) {
if (log != null)
log.append("Invalid b64 for" + key + " From: " + sub.getLocation());
}
}
}
}
/**
* Run an update, using the Map settings to provide the parameters.
*
@ -120,7 +190,35 @@ public class Daemon {
.get("proxy_host"), Integer.parseInt(settings.get("proxy_port")));
Log log = new Log(logFile);
update(master, router, published, subscriptions, log);
if (true)
update(getNamingService(), published, subscriptions, log);
else
update(master, router, published, subscriptions, log);
}
/** depth-first search */
private static NamingService searchNamingService(NamingService ns, String srch)
{
String name = ns.getName();
if (name == srch)
return ns;
List<NamingService> list = ns.getNamingServices();
if (list != null) {
for (NamingService nss : list) {
NamingService rv = searchNamingService(nss, srch);
if (rv != null)
return rv;
}
}
return null;
}
/** @return the NamingService for the current file name, or the root NamingService */
private static NamingService getNamingService()
{
NamingService root = I2PAppContext.getGlobalContext().namingService();
NamingService rv = searchNamingService(root, "hosts.txt");
return rv != null ? rv : root;
}
/**