=== modified file 'src/client.c'
--- old/src/client.c	2013-09-27 14:48:19 +0000
+++ new/src/client.c	2013-09-27 19:11:46 +0000
@@ -336,9 +336,9 @@
     SSL_set_ex_data(c->ssl, cli_index, c); /* for callbacks */
     if(c->opt->option.client) {
 #ifndef OPENSSL_NO_TLSEXT
-        if(c->opt->sni) {
-            s_log(LOG_DEBUG, "SNI: sending servername: %s", c->opt->sni);
-            if(!SSL_set_tlsext_host_name(c->ssl, c->opt->sni)) {
+        if(c->opt->servername_to_request) {
+            s_log(LOG_DEBUG, "SNI: sending servername: %s", c->opt->servername_to_request);
+            if(!SSL_set_tlsext_host_name(c->ssl, c->opt->servername_to_request)) {
                 sslerror("SSL_set_tlsext_host_name");
                 longjmp(c->err, 1);
             }

=== modified file 'src/options.c'
--- old/src/options.c	2013-09-27 14:48:19 +0000
+++ new/src/options.c	2013-09-27 19:21:18 +0000
@@ -1607,7 +1607,14 @@
     case CMD_EXEC:
         if(strcasecmp(opt, "sni"))
             break;
-        section->sni=str_dup(arg);
+        if(!section->sni_list_tail) {
+            section->sni_list_head=str_alloc(sizeof(SNI_OPT));
+            section->sni_list_tail=section->sni_list_head;
+        } else {
+            section->sni_list_tail->next=str_alloc(sizeof(SNI_OPT));
+            section->sni_list_tail=section->sni_list_tail->next;
+        }
+        section->sni_list_tail->sni=strdup(arg);
         return NULL; /* OK */
     case CMD_END:
         tmpstr=init_sni(section);
@@ -2126,54 +2133,68 @@
 
 #ifndef OPENSSL_NO_TLSEXT
 static char *init_sni(SERVICE_OPTIONS *section) {
+    SNI_OPT *tmpsni;
     char *tmpstr;
     SERVICE_OPTIONS *tmpsrv;
 
-    /* server mode: update servername_list based on SNI option */
-    if(!section->option.client && section->sni) {
-        tmpstr=strchr(section->sni, ':');
-        if(!tmpstr)
-            return "Invalid SNI parameter format";
-        *tmpstr++='\0';
-        for(tmpsrv=new_service_options.next; tmpsrv; tmpsrv=tmpsrv->next)
-            if(!strcmp(tmpsrv->servname, section->sni))
-                break;
-        if(!tmpsrv)
-            return "SNI section name not found";
-        if(tmpsrv->option.client)
-            return "SNI master service is a TLS client";
-        if(tmpsrv->servername_list_tail) {
-            tmpsrv->servername_list_tail->next=str_alloc(sizeof(SERVERNAME_LIST));
-            tmpsrv->servername_list_tail=tmpsrv->servername_list_tail->next;
-        } else { /* first virtual service */
-            tmpsrv->servername_list_head=
-                tmpsrv->servername_list_tail=
-                str_alloc(sizeof(SERVERNAME_LIST));
-            tmpsrv->ssl_options|=SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
-        }
-        tmpsrv->servername_list_tail->servername=str_dup(tmpstr);
-        tmpsrv->servername_list_tail->opt=section;
-        tmpsrv->servername_list_tail->next=NULL;
-        section->option.sni=1;
-        /* always negotiate a new session on renegotiation, as the SSL
-         * context settings (including access control) may be different */
-        section->ssl_options|=SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
+    /* server mode: update servername_list based on SNI options */
+    if(!section->option.client && section->sni_list_head) {
+        tmpsni=section->sni_list_head;
+        do {
+            tmpstr=strchr(tmpsni->sni, ':');
+            if(!tmpstr)
+                return "Invalid SNI parameter format";
+            *tmpstr++='\0';
+            for(tmpsrv=new_service_options.next; tmpsrv; tmpsrv=tmpsrv->next)
+                if(!strcmp(tmpsrv->servname, tmpsni->sni))
+                    break;
+            if(!tmpsrv)
+                return "SNI section name not found";
+            if(tmpsrv->option.client)
+                return "SNI master service is a TLS client";
+            if(tmpsrv->servername_list_tail) {
+                tmpsrv->servername_list_tail->next=str_alloc(sizeof(SERVERNAME_LIST));
+                tmpsrv->servername_list_tail=tmpsrv->servername_list_tail->next;
+            } else { /* first virtual service */
+                tmpsrv->servername_list_head=
+                    tmpsrv->servername_list_tail=
+                    str_alloc(sizeof(SERVERNAME_LIST));
+                tmpsrv->ssl_options|=SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
+            }
+            tmpsrv->servername_list_tail->servername=str_dup(tmpstr);
+            tmpsrv->servername_list_tail->opt=section;
+            tmpsrv->servername_list_tail->next=NULL;
+            section->option.sni=1;
+            /* always negotiate a new session on renegotiation, as the
+             * SSL context settings (including access control) may be
+             * different */
+            section->ssl_options|=SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
+            tmpsni=tmpsni->next;
+        } while(tmpsni);
     }
 
     /* client mode: setup SNI default based on 'protocolHost' and 'connect' options */
-    if(section->option.client && !section->sni) {
-        /* setup host_name for SNI, prefer SNI and protocolHost if specified */
-        if(section->protocol_host) /* 'protocolHost' option */
-            section->sni=str_dup(section->protocol_host);
-        else if(section->connect_list) /* 'connect' option */
-            section->sni=str_dup(section->connect_list->name); /* first hostname */
-        if(section->sni) { /* either 'protocolHost' or 'connect' specified */
-            tmpstr=strrchr(section->sni, ':');
-            if(tmpstr) { /* 'host:port' -> drop ':port' */
-                *tmpstr='\0';
-            } else { /* 'port' -> default to 'localhost' */
-                str_free(section->sni);
-                section->sni=str_dup("localhost");
+    if(section->option.client) {
+        if(section->sni_list_head) {
+            if(section->sni_list_head->next)
+                return "Only one sni option is permitted in client mode";
+            section->servername_to_request=strdup(section->sni_list_head->sni);
+        }
+        if(!section->servername_to_request) {
+            /* setup host_name for SNI, prefer SNI and protocolHost if
+             * specified */
+            if(section->protocol_host) /* 'protocolHost' option */
+                section->servername_to_request=str_dup(section->protocol_host);
+            else if(section->connect_list) /* 'connect' option */
+                section->servername_to_request=str_dup(section->connect_list->name); /* first hostname */
+            if(section->servername_to_request) { /* either 'protocolHost' or 'connect' specified */
+                tmpstr=strrchr(section->servername_to_request, ':');
+                if(tmpstr) { /* 'host:port' -> drop ':port' */
+                    *tmpstr='\0';
+                } else { /* 'port' -> default to 'localhost' */
+                    str_free(section->servername_to_request);
+                    section->servername_to_request=str_dup("localhost");
+                }
             }
         }
     }

=== modified file 'src/prototypes.h'
--- old/src/prototypes.h	2013-09-27 14:48:19 +0000
+++ new/src/prototypes.h	2013-09-27 19:10:58 +0000
@@ -124,6 +124,11 @@
 typedef struct servername_list_struct SERVERNAME_LIST;/* forward declaration */
 #endif
 
+typedef struct sni_opt_struct {
+    const char *sni;
+    struct sni_opt_struct *next;
+} SNI_OPT;
+
 typedef struct service_options_struct {
     struct service_options_struct *next;   /* next node in the services list */
     SSL_CTX *ctx;                                            /*  SSL context */
@@ -156,7 +161,8 @@
     SSL_METHOD *client_method, *server_method;
     SOCKADDR_UNION sessiond_addr;
 #ifndef OPENSSL_NO_TLSEXT
-    char *sni;
+    SNI_OPT *sni_list_head, *sni_list_tail;
+    char *servername_to_request;
     SERVERNAME_LIST *servername_list_head, *servername_list_tail;
 #endif
 #ifndef OPENSSL_NO_ECDH

