diff --git a/src/preload.c b/src/preload.c
index fb2149b..b597616 100644
--- a/src/preload.c
+++ b/src/preload.c
@@ -50,6 +50,8 @@
  #include <netinet/tcp.h>
  #include <unistd.h>
  #include <semaphore.h>
+#include <ctype.h>
+#include <stdlib.h>

  #include <rdma/rdma_cma.h>
  #include <rdma/rdma_verbs.h>
@@ -122,6 +124,217 @@ struct fd_info {
         atomic_t refcnt;
  };

+typedef struct {
+       char *name;
+       uint32_t domain;
+       uint32_t type;
+       uint32_t protocol;
+} config_entry_t;
+
+static config_entry_t *entryp;
+static int16_t nentries;
+static int16_t config_avail;
+extern char *program_invocation_short_name;
+
+/* scan preload configuration file and create
+ * in-memory config store
+ * should be called only once under lock
+ */
+static int scan_preload_config(void)
+{
+       FILE *fp;
+       char line[512];
+       char *lp, *cp, *str1, *str2;
+       char *token, *subtoken, *saveptr1, *saveptr2;
+       int i, j, ret = 0;
+
+       fp = fopen(RS_CONF_DIR "/preload_config", "r");
+       if (fp == NULL) {
+               return -1;
+       }
+
+       while ((lp = fgets(line, sizeof(line), fp)) != NULL) {
+
+               /* trim white space at the beginning of each line */
+               while (*lp != '\0') {
+                       if (isspace(*lp)) {
+                               lp++;
+                               continue;
+                       } else {
+                               break;
+                       }
+               }
+
+               /* skip comment and blank lines */
+               if (*lp == '\0' || *lp == '#') {
+                       continue;
+               }
+
+               /* trim comments and newlines at the end of each line */
+               if ((cp = strpbrk(lp, "#\n")) != NULL) {
+                       *cp = '\0';
+               }
+
+               /* now allocate memory for new configuration entry */
+               entryp = (config_entry_t *) realloc(entryp, (nentries + 
1) *
+                                               sizeof(config_entry_t));
+               if (!entryp) {
+                       ret = -1;
+                       goto scan_done;
+               }
+               memset(entryp + nentries, '\0', sizeof(config_entry_t));
+
+               /* tokenize the retrieved line and parse individual 
fields */
+               for (i = 1, str1 = lp; ; i++, str1 = NULL) {
+                       token = strtok_r(str1, " \t", &saveptr1);
+                       if (token == NULL) {
+                               break;
+                       }
+
+                       /* first field should contain program name */
+                       if (i == 1) {
+                               entryp[nentries].name = (char *) 
malloc((strlen(token) + 1));
+                               if (!entryp[nentries].name) {
+                                       ret = -1;
+                                       goto scan_done;
+                               }
+                               memcpy(entryp[nentries].name, token, 
strlen(token) + 1);
+                               continue;
+                       }
+
+                       /* second field onwards can contain multiple 
entries
+                        * separated by commas
+                        */
+                       for (j = 1, str2 = token; ; j++, str2 = NULL) {
+                               subtoken = strtok_r(str2, ",", 
&saveptr2);
+                               if (subtoken == NULL) {
+                                       break;
+                               }
+
+                               /* second field is socket domain
+                                * rsocket currently recognizes only 
AF_INET, AF_INET6
+                                * and AF_IB domains
+                                * '*' implies all the valid domains
+                                */
+                               if (i == 2) {
+                                       if (*subtoken == '*') {
+                                               entryp[nentries].domain 
|= (1 << AF_INET);
+                                               entryp[nentries].domain 
|= (1 << AF_INET6);
+                                               entryp[nentries].domain 
|= (1 << AF_IB);
+                                               break;
+                                       } else if (strcmp(subtoken, 
"inet6") == 0) {
+                                               entryp[nentries].domain 
|= (1 << AF_INET6);
+                                       } else if (strcmp(subtoken, 
"inet") == 0) {
+                                               entryp[nentries].domain 
|= (1 << AF_INET);
+                                       } else if (strcmp(subtoken, 
"ib") == 0) {
+                                               entryp[nentries].domain 
|= (1 << AF_IB);
+                                       }
+                                       continue;
+                               }
+
+                               /* third field is socket type
+                                * rsocket currently recognizes only 
SOCK_STREAM and
+                                * SOCK_DGRAM types
+                                * '*' implies all the valid types
+                                */
+                               if (i == 3) {
+                                       if (*subtoken == '*') {
+                                               entryp[nentries].type |= 
(1 << SOCK_STREAM);
+                                               entryp[nentries].type |= 
(1 << SOCK_DGRAM);
+                                               break;
+                                       } else if (strcmp(subtoken, 
"stream") == 0) {
+                                               entryp[nentries].type |= 
(1 << SOCK_STREAM);
+                                       } else if (strcmp(subtoken, 
"dgram") == 0) {
+                                               entryp[nentries].type |= 
(1 << SOCK_DGRAM);
+                                       }
+                                       continue;
+                               }
+
+                               /* fourth field is socket protocol
+                                * rsocket currently recgonizes only 
IPPROTO_TCP and
+                                * IPPROTO_UDP protocols
+                                * '*' implies all the valid protocols
+                                */
+                               if (i == 4) {
+                                       if (*subtoken == '*') {
+                                               
entryp[nentries].protocol |= (1 << IPPROTO_TCP);
+                                               
entryp[nentries].protocol |= (1 << IPPROTO_UDP);
+                                               break;
+                                       } else if (strcmp(subtoken, 
"tcp") == 0) {
+                                               
entryp[nentries].protocol |= (1 << IPPROTO_TCP);
+                                       } else if (strcmp(subtoken, 
"udp") == 0) {
+                                               
entryp[nentries].protocol |= (1 << IPPROTO_UDP);
+                                       }
+                                       continue;
+                               }
+                       }
+               }
+               nentries += 1;
+       }
+
+scan_done:
+       fclose(fp);
+       return ret;
+}
+
+/* free in-memory config store
+ * should be called only once during finalization
+ */
+static void free_preload_config(void)
+{
+       int i;
+
+       if (entryp) {
+               for (i = 0; i < nentries; i++) {
+                       if (entryp[i].name) {
+                               free(entryp[i].name);
+                       }
+               }
+               free(entryp);
+       }
+
+       return;
+}
+
+/* check whether interception is required for this socket
+ * compares the provided attributes with that available in the 
in-memory
+ * data store for the current process
+ * sets-up in-memory config store if it's already not done
+ */
+static int intercept_socket(int domain, int type, int protocol)
+{
+       int i;
+
+       /* locate the config entry */
+       for (i = 0; i < nentries; i++) {
