diff --git a/src/net/sf/briar/plugins/modem/Modem.java b/src/net/sf/briar/plugins/modem/Modem.java
index d85a7bfacd4ba257d113aa250a9dcf26cb1ace8c..e758ef8b820dfcca3ce8bb6070f2c424ce8e3726 100644
--- a/src/net/sf/briar/plugins/modem/Modem.java
+++ b/src/net/sf/briar/plugins/modem/Modem.java
@@ -4,17 +4,22 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
+/**
+ * A modem that can be used for multiple sequential incoming and outgoing
+ * calls. If the modem or its input or output streams throw an exception it
+ * cannot continue to be used.
+ */
 interface Modem {
 
 	/**
-	 * Call this method once after creating the modem. If an exception is
-	 * thrown, the modem cannot be used.
+	 * Call this method once after creating the modem and before making any
+	 * calls.
 	 */
 	void init() throws IOException;
 
 	/**
 	 * Initiates an outgoing call and returns true if the call connects. If the
-	 * call does not connect the modem is hung up.
+	 * call does not connect the modem is hung up and can continue to be used.
 	 */
 	boolean dial(String number) throws IOException;
 
diff --git a/src/net/sf/briar/plugins/modem/ModemImpl.java b/src/net/sf/briar/plugins/modem/ModemImpl.java
index be4515fa57adf1f24d0bb6d27bca7e333ce0a7c7..d66907ce0962e9c75723c24ba15fc92fe8629c22 100644
--- a/src/net/sf/briar/plugins/modem/ModemImpl.java
+++ b/src/net/sf/briar/plugins/modem/ModemImpl.java
@@ -72,6 +72,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 			port.writeBytes("ATZ\r\n".getBytes("US-ASCII")); // Reset
 			port.writeBytes("ATE0\r\n".getBytes("US-ASCII")); // Echo off
 		} catch(SerialPortException e) {
+			tryToClose(port);
 			throw new IOException(e.toString());
 		}
 		try {
@@ -84,6 +85,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		} catch(InterruptedException e) {
 			if(LOG.isLoggable(WARNING))
 				LOG.warning("Interrupted while initialising modem");
+			tryToClose(port);
 			Thread.currentThread().interrupt();
 			throw new IOException("Interrupted while initialising modem");
 		}
@@ -99,6 +101,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		try {
 			port.writeBytes(("ATDT" + number + "\r\n").getBytes("US-ASCII"));
 		} catch(SerialPortException e) {
+			tryToClose(port);
 			throw new IOException(e.toString());
 		}
 		try {
@@ -108,6 +111,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		} catch(InterruptedException e) {
 			if(LOG.isLoggable(WARNING))
 				LOG.warning("Interrupted while connecting outgoing call");
+			tryToClose(port);
 			Thread.currentThread().interrupt();
 			throw new IOException("Interrupted while connecting outgoing call");
 		}
@@ -129,6 +133,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		try {
 			port.setDTR(false);
 		} catch(SerialPortException e) {
+			tryToClose(port);
 			throw new IOException(e.toString());
 		}
 		received.add(new byte[0]); // Empty buffer indicates EOF
@@ -155,8 +160,10 @@ class ModemImpl implements Modem, SerialPortEventListener {
 	}
 
 	private void handleText(byte[] b) throws IOException {
-		if(lineLen + b.length > MAX_LINE_LENGTH)
+		if(lineLen + b.length > MAX_LINE_LENGTH) {
+			tryToClose(port);
 			throw new IOException("Line too long");
+		}
 		for(int i = 0; i < b.length; i++) {
 			line[lineLen] = b[i];
 			if(b[i] == '\n') {
@@ -201,6 +208,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		try {
 			port.writeBytes("ATA\r\n".getBytes("US-ASCII"));
 		} catch(SerialPortException e) {
+			tryToClose(port);
 			throw new IOException(e.toString());
 		}
 		try {
@@ -210,6 +218,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		} catch(InterruptedException e) {
 			if(LOG.isLoggable(WARNING))
 				LOG.warning("Interrupted while connecting incoming call");
+			tryToClose(port);
 			Thread.currentThread().interrupt();
 			throw new IOException("Interrupted while connecting incoming call");
 		}
@@ -217,7 +226,15 @@ class ModemImpl implements Modem, SerialPortEventListener {
 		else hangUp();
 	}
 
-	private static class ModemInputStream extends InputStream {
+	private void tryToClose(SerialPort port) {
+		try {
+			port.closePort();
+		} catch(SerialPortException e) {
+			if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
+		}
+	}
+
+	private class ModemInputStream extends InputStream {
 
 		private final BlockingQueue<byte[]> received;
 
@@ -262,6 +279,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 				} catch(InterruptedException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.warning("Interrupted while reading");
+					tryToClose(port);
 					Thread.currentThread().interrupt();
 					throw new IOException(e.toString());
 				}
@@ -277,6 +295,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 			try {
 				port.writeByte((byte) b);
 			} catch(SerialPortException e) {
+				tryToClose(port);
 				throw new IOException(e.toString());
 			}
 		}
@@ -286,6 +305,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
 			try {
 				port.writeBytes(b);
 			} catch(SerialPortException e) {
+				tryToClose(port);
 				throw new IOException(e.toString());
 			}
 		}