diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
index 7e31a877c02f00f1e1f819d1c20dd485b7943ed7..a4aede92e3d49a1ce3c0a8a5ca63533d39df1e07 100644
--- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
+++ b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
@@ -1,6 +1,7 @@
 package org.briarproject.transport;
 
 import org.briarproject.api.TransportId;
+import org.briarproject.api.contact.Contact;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.SecretKey;
@@ -9,6 +10,7 @@ import org.briarproject.api.db.DatabaseExecutor;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.Transaction;
 import org.briarproject.api.event.ContactRemovedEvent;
+import org.briarproject.api.event.ContactStatusChangedEvent;
 import org.briarproject.api.event.Event;
 import org.briarproject.api.event.EventListener;
 import org.briarproject.api.event.TransportAddedEvent;
@@ -19,6 +21,7 @@ import org.briarproject.api.system.Timer;
 import org.briarproject.api.transport.KeyManager;
 import org.briarproject.api.transport.StreamContext;
 
+import java.util.Collection;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
@@ -39,6 +42,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 	private final ExecutorService dbExecutor;
 	private final Timer timer;
 	private final Clock clock;
+	private final Map<ContactId, Boolean> activeContacts;
 	private final ConcurrentHashMap<TransportId, TransportKeyManager> managers;
 
 	@Inject
@@ -50,20 +54,26 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 		this.dbExecutor = dbExecutor;
 		this.timer = timer;
 		this.clock = clock;
+		// Use a ConcurrentHashMap as a thread-safe set
+		activeContacts = new ConcurrentHashMap<ContactId, Boolean>();
 		managers = new ConcurrentHashMap<TransportId, TransportKeyManager>();
 	}
 
 	@Override
 	public boolean start() {
 		try {
+			Collection<Contact> contacts;
 			Map<TransportId, Integer> latencies;
 			Transaction txn = db.startTransaction();
 			try {
+				contacts = db.getContacts(txn);
 				latencies = db.getTransportLatencies(txn);
 				txn.setComplete();
 			} finally {
 				db.endTransaction(txn);
 			}
+			for (Contact c : contacts)
+				if (c.isActive()) activeContacts.put(c.getId(), true);
 			for (Entry<TransportId, Integer> e : latencies.entrySet())
 				addTransport(e.getKey(), e.getValue());
 		} catch (DbException e) {
@@ -85,13 +95,33 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 	}
 
 	public StreamContext getStreamContext(ContactId c, TransportId t) {
+		// Don't allow outgoing streams to inactive contacts
+		if (!activeContacts.containsKey(c)) return null;
 		TransportKeyManager m = managers.get(t);
 		return m == null ? null : m.getStreamContext(c);
 	}
 
 	public StreamContext getStreamContext(TransportId t, byte[] tag) {
 		TransportKeyManager m = managers.get(t);
-		return m == null ? null : m.recogniseTag(tag);
+		if (m == null) return null;
+		StreamContext ctx = m.getStreamContext(tag);
+		if (ctx == null) return null;
+		// Activate the contact if not already active
+		if (!activeContacts.containsKey(ctx.getContactId())) {
+			try {
+				Transaction txn = db.startTransaction();
+				try {
+					db.setContactActive(txn, ctx.getContactId(), true);
+					txn.setComplete();
+				} finally {
+					db.endTransaction(txn);
+				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				return null;
+			}
+		}
+		return ctx;
 	}
 
 	public void eventOccurred(Event e) {
@@ -102,6 +132,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 			removeTransport(((TransportRemovedEvent) e).getTransportId());
 		} else if (e instanceof ContactRemovedEvent) {
 			removeContact(((ContactRemovedEvent) e).getContactId());
+		} else if (e instanceof ContactStatusChangedEvent) {
+			ContactStatusChangedEvent c = (ContactStatusChangedEvent) e;
+			if (c.isActive()) activeContacts.put(c.getContactId(), true);
+			else activeContacts.remove(c.getContactId());
 		}
 	}
 
@@ -121,6 +155,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 	}
 
 	private void removeContact(final ContactId c) {
+		activeContacts.remove(c);
 		dbExecutor.execute(new Runnable() {
 			public void run() {
 				for (TransportKeyManager m : managers.values())
diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManager.java b/briar-core/src/org/briarproject/transport/TransportKeyManager.java
index ce15995ac47fc18d8a16ae8e2c1d6fa2fecc27e7..b380765787d532ff011c9d021e64581d80d5e91e 100644
--- a/briar-core/src/org/briarproject/transport/TransportKeyManager.java
+++ b/briar-core/src/org/briarproject/transport/TransportKeyManager.java
@@ -207,7 +207,7 @@ class TransportKeyManager extends TimerTask {
 		}
 	}
 
-	StreamContext recogniseTag(byte[] tag) {
+	StreamContext getStreamContext(byte[] tag) {
 		lock.lock();
 		try {
 			// Look up the incoming keys for the tag