Commit 7817a7cc authored by iwakeh's avatar iwakeh
Browse files

Prevent NPE and unclosed connections.

parent 02c9c5fb
...@@ -13,6 +13,7 @@ import java.sql.CallableStatement; ...@@ -13,6 +13,7 @@ import java.sql.CallableStatement;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -245,77 +246,82 @@ public class QueryServlet extends HttpServlet { ...@@ -245,77 +246,82 @@ public class QueryServlet extends HttpServlet {
SortedSet<Long> allValidAfters = new TreeSet<>(); SortedSet<Long> allValidAfters = new TreeSet<>();
List<QueryResponse.Match> matches = new ArrayList<>(); List<QueryResponse.Match> matches = new ArrayList<>();
SortedSet<String> allAddresses = new TreeSet<>(); SortedSet<String> allAddresses = new TreeSet<>();
try { final long requestedConnection = System.currentTimeMillis();
final long requestedConnection = System.currentTimeMillis(); Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Connection conn = this.ds.getConnection(); try (Connection conn = this.ds.getConnection()) {
CallableStatement cs = conn.prepareCall(String.format( try (CallableStatement cs = conn.prepareCall(String.format(
"{call search_by_address%s_date(?, ?)}", "{call search_by_address%s_date(?, ?)}",
relayIp.contains(":") ? 48 : 24)); relayIp.contains(":") ? 48 : 24))) {
cs.setString(1, address24Or48Hex); cs.setString(1, address24Or48Hex);
Calendar utcCalendar = Calendar.getInstance( cs.setDate(2, new java.sql.Date(timestamp), utcCalendar);
TimeZone.getTimeZone("UTC")); try (ResultSet rs = cs.executeQuery()) {
cs.setDate(2, new java.sql.Date(timestamp), utcCalendar); while (rs.next()) {
ResultSet rs = cs.executeQuery(); Timestamp ts = rs.getTimestamp(2, utcCalendar);
while (rs.next()) { if (null == ts) {
long validafter = rs.getTimestamp(2, utcCalendar).getTime(); continue;
allValidAfters.add(validafter); }
byte[] rawstatusentry = rs.getBytes(1); long validafter = ts.getTime();
if (null == rawstatusentry) { allValidAfters.add(validafter);
continue; byte[] rawstatusentry = rs.getBytes(1);
} if (null == rawstatusentry) {
SortedSet<String> addresses = new TreeSet<>(); continue;
SortedSet<String> addressesHex = new TreeSet<>(); }
String nickname = null; SortedSet<String> addresses = new TreeSet<>();
Boolean exit = null; SortedSet<String> addressesHex = new TreeSet<>();
for (String line : new String(rawstatusentry).split("\n")) { String nickname = null;
if (line.startsWith("r ")) { Boolean exit = null;
String[] parts = line.split(" "); for (String line : new String(rawstatusentry).split("\n")) {
nickname = parts[1]; if (line.startsWith("r ")) {
addresses.add(parts[6]); String[] parts = line.split(" ");
addressesHex.add(this.convertIpV4ToHex(parts[6])); nickname = parts[1];
} else if (line.startsWith("a ")) { addresses.add(parts[6]);
String address = line.substring("a ".length(), addressesHex.add(this.convertIpV4ToHex(parts[6]));
line.lastIndexOf(":")); } else if (line.startsWith("a ")) {
addresses.add(address); String address = line.substring("a ".length(),
String orAddressHex = !address.contains(":") line.lastIndexOf(":"));
? this.convertIpV4ToHex(address) addresses.add(address);
: this.convertIpV6ToHex(address); String orAddressHex = !address.contains(":")
addressesHex.add(orAddressHex); ? this.convertIpV4ToHex(address)
} else if (line.startsWith("p ")) { : this.convertIpV6ToHex(address);
exit = !line.equals("p reject 1-65535"); addressesHex.add(orAddressHex);
} else if (line.startsWith("p ")) {
exit = !line.equals("p reject 1-65535");
}
}
String exitaddress = rs.getString(4);
if (exitaddress != null && exitaddress.length() > 0) {
addresses.add(exitaddress);
addressesHex.add(this.convertIpV4ToHex(exitaddress));
}
allAddresses.addAll(addresses);
if (!addressesHex.contains(addressHex)) {
continue;
}
String validAfterString = validAfterTimeFormat.format(validafter);
String fingerprint = rs.getString(3).toUpperCase();
QueryResponse.Match match = new QueryResponse.Match();
match.timestamp = validAfterString;
match.addresses = addresses.toArray(new String[0]);
match.fingerprint = fingerprint;
match.nickname = nickname;
match.exit = exit;
matches.add(match);
} }
} catch (SQLException e) {
this.logger.warn("Result set error. Returning 'null'.", e);
return null;
} }
String exitaddress = rs.getString(4); this.logger.info("Returned a database connection to the pool after {}"
if (exitaddress != null && exitaddress.length() > 0) { + " millis.", System.currentTimeMillis() - requestedConnection);
addresses.add(exitaddress); } catch (SQLException e) {
addressesHex.add(this.convertIpV4ToHex(exitaddress)); this.logger.warn("Callable statement error. Returning 'null'.", e);
} return null;
allAddresses.addAll(addresses);
if (!addressesHex.contains(addressHex)) {
continue;
}
String validAfterString = validAfterTimeFormat.format(validafter);
String fingerprint = rs.getString(3).toUpperCase();
QueryResponse.Match match = new QueryResponse.Match();
match.timestamp = validAfterString;
match.addresses = addresses.toArray(new String[0]);
match.fingerprint = fingerprint;
match.nickname = nickname;
match.exit = exit;
matches.add(match);
} }
rs.close(); } catch (Throwable e) { // Catch all problems left.
cs.close();
conn.close();
this.logger.info("Returned a database connection to the pool after {}"
+ " millis.", System.currentTimeMillis() - requestedConnection);
} catch (SQLException e) {
/* Nothing found. */
this.logger.warn("Database error. Returning 'null'.", e); this.logger.warn("Database error. Returning 'null'.", e);
return null; return null;
} }
/* Create a query response object. */
QueryResponse response = new QueryResponse(); QueryResponse response = new QueryResponse();
response.queryAddress = relayIp; response.queryAddress = relayIp;
response.queryDate = dateFormat.format(timestamp); response.queryDate = dateFormat.format(timestamp);
...@@ -352,7 +358,6 @@ public class QueryServlet extends HttpServlet { ...@@ -352,7 +358,6 @@ public class QueryServlet extends HttpServlet {
} }
} }
/* Return the query response. */
return response; return response;
} }
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment