be more careful about closing ResultSets in Graylist
[org.ibex.mail.git] / src / org / ibex / mail / Graylist.java
index ec1fe12..d31ae00 100644 (file)
@@ -9,13 +9,11 @@ import java.sql.Timestamp;
 
 public class Graylist extends SqliteDB {
 
-    public Graylist(String filename) {
-        super(filename,
-              new String[] {
-                  "create table if not exists 'whitelist' (ip unique)",
-                  "create table if not exists 'graylist' (ip,fromaddr,toaddr,date, primary key(ip,fromaddr,toaddr))"
-              });
-        reap("graylist", "date");
+    public Graylist(String filename) throws SQLException {
+        super(filename);
+        SqliteTable whitelist = getTable("whitelist", "(ip unique)");
+        SqliteTable graylist  = getTable("graylist",  "(ip,fromaddr,toaddr,date,PRIMARY KEY(ip,fromaddr,toaddr))");
+        graylist.reap("date");
     }
 
     public synchronized void addWhitelist(InetAddress ip) {
@@ -30,8 +28,13 @@ public class Graylist extends SqliteDB {
         try {
             PreparedStatement check = conn.prepareStatement("select * from 'whitelist' where ip=?");
             check.setString(1, ip.getHostAddress());
-            ResultSet rs = check.executeQuery();
-            return !rs.isAfterLast();
+            ResultSet rs = null;
+            boolean ret;
+            try {
+                rs = check.executeQuery();
+                ret = !rs.isAfterLast();
+            } finally { close(rs); }
+            return ret;
         } catch (SQLException e) { throw new RuntimeException(e); }
     }
 
@@ -39,12 +42,15 @@ public class Graylist extends SqliteDB {
         try {
             PreparedStatement check =
                 conn.prepareStatement("select date from graylist where ip=? and fromaddr=? and toaddr=?");
-            check.setString(1, ip.getHostAddress());
+            check.setString(1, graylistAddress(ip));
             check.setString(2, from);
             check.setString(3, to);
-            ResultSet rs = check.executeQuery();
-            if (rs.isAfterLast()) return 0;
-            return rs.getTimestamp(1).getTime();
+            ResultSet rs = null;
+            try {
+                rs = check.executeQuery();
+                if (rs.isAfterLast()) return 0;
+                return rs.getTimestamp(1).getTime();
+            } finally { close(rs); }
         } catch (SQLException e) { throw new RuntimeException(e); }
     }
 
@@ -52,7 +58,7 @@ public class Graylist extends SqliteDB {
         try {
             PreparedStatement check =
                 conn.prepareStatement("insert or replace into graylist (ip,fromaddr,toaddr,date) values(?,?,?,?)");
-            check.setString(1, ip.getHostAddress());
+            check.setString(1, graylistAddress(ip));
             check.setString(2, from);
             check.setString(3, to);
             check.setTimestamp(4, new Timestamp(date));
@@ -60,5 +66,19 @@ public class Graylist extends SqliteDB {
         } catch (SQLException e) { throw new RuntimeException(e); }
     }
 
+    //
+    // this is mostly to deal with comcast's pathetic retry policy and
+    // rotating pool of outbound servers
+    // see: http://lists.puremagic.com/pipermail/greylist-users/2006-November/001255.html
+    //
+    private static String graylistAddress(InetAddress ipa) {
+        byte[] ip = ipa.getAddress();
+        return
+            (ip[0] & 0xff)+"."+
+            (ip[1] & 0xff)+"."+
+            (ip[2] & 0xff)+"."+
+            ".0";
+    }
+
 }