diff --git a/include/libssh2.h b/include/libssh2.h
index 95c557b..ce03143 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -422,6 +422,20 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session,
 
 LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
 
+/* libssh2_session_get_timeout
+ *
+ * Returns a session's timoout
+ */
+LIBSSH2_API int libssh2_session_get_timeout(LIBSSH2_SESSION *session);
+
+/* libssh2_session_set_timeout
+ *
+ * Set a session's timeout (in msec) for blocking mode,
+ * or 0 to disable timeouts.
+ */
+LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION *session,
+                                             int timeout);
+
 LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session,
                                              int hash_type);
 
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 54d4d16..fa9ef79 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -735,6 +735,9 @@ struct _LIBSSH2_SESSION
     int socket_prev_blockstate; /* stores the state of the socket blockiness
                                    when libssh2_session_startup() is called */
 
+    /* Timeout used when blocking API behavior is active */
+    int api_timeout;
+
     /* Error tracking */
     const char *err_msg;
     int err_code;
diff --git a/src/session.c b/src/session.c
index f6498e4..c6a6867 100644
--- a/src/session.c
+++ b/src/session.c
@@ -540,16 +540,22 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
 int _libssh2_wait_socket(LIBSSH2_SESSION *session)
 {
     int rc;
-    int seconds_to_next;
+    int ms_to_next;
     int dir;
 
-    rc = libssh2_keepalive_send (session, &seconds_to_next);
+    rc = libssh2_keepalive_send (session, &ms_to_next);
     if (rc < 0)
         return rc;
     else {
+        ms_to_next *= 1000; /* convert the timeout to milliseconds */
+
         /* figure out what to wait for */
         dir = libssh2_session_block_directions(session);
 
+        if (session->api_timeout &&
+            (session->api_timeout < ms_to_next))
+            ms_to_next = session->api_timeout;
+
         {
 #ifdef HAVE_POLL
             struct pollfd sockets[1];
@@ -564,7 +570,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
             if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
                 sockets[0].events |= POLLOUT;
 
-            rc = poll(sockets, 1, seconds_to_next ? seconds_to_next / 1000 : -1);
+            rc = poll(sockets, 1, ms_to_next ? ms_to_next : -1);
 #else
             fd_set rfd;
             fd_set wfd;
@@ -572,8 +578,9 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
             fd_set *readfd = NULL;
             struct timeval tv;
 
-            tv.tv_sec = seconds_to_next;
-            tv.tv_usec = 0;
+            tv.tv_sec = ms_to_next/1000;  /* full seconds */
+            ms_to_next -= tv.tv_sec*1000; /* remove seconds we stored */
+            tv.tv_usec = ms_to_next*1000; /* remainder turned into us */
 
             if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
                 FD_ZERO(&rfd);
@@ -590,7 +597,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
             /* Note that this COULD be made to use a timeout that perhaps
                could be customizable by the app or something... */
             rc = select(session->socket_fd + 1, readfd, writefd, NULL,
-                        seconds_to_next ? &tv : NULL);
+                        ms_to_next ? &tv : NULL);
 #endif
         }
     }
@@ -1245,6 +1252,27 @@ libssh2_session_get_blocking(LIBSSH2_SESSION * session)
     return session->api_block_mode;
 }
 
+/* libssh2_session_set_timeout
+ *
+ * Set a session's timeout (in msec) for blocking mode,
+ * or 0 to disable timeouts.
+ */
+LIBSSH2_API void
+libssh2_session_set_timeout(LIBSSH2_SESSION *session, int timeout)
+{
+    session->api_timeout = timeout;
+}
+
+/* libssh2_session_get_timeout
+ *
+ * Returns a session's timeout, or 0 if disabled
+ */
+LIBSSH2_API int
+libssh2_session_get_timeout(LIBSSH2_SESSION *session)
+{
+    return session->api_timeout;
+}
+
 /*
  * libssh2_poll_channel_read
  *
