NOEXPORT char *sni_init(SERVICE_OPTIONS *section) {
    char *tmp_str;
    SERVICE_OPTIONS *tmpsrv;

    /* server mode: update servername_list based on the SNI option */
    if(!section->option.client && section->sni) {
        tmp_str=strchr(section->sni, ':');
        if(!tmp_str)
            return "Invalid SNI parameter format";
        *tmp_str++='\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_detached(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_detached(sizeof(SERVERNAME_LIST));
            tmpsrv->ssl_options_set|=
                SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
        }
        /* a slave section reference is needed to prevent a race condition
           while switching to a section after configuration file reload */
        service_up_ref(section);
        tmpsrv->servername_list_tail->servername=str_dup_detached(tmp_str);
        tmpsrv->servername_list_tail->opt=section;
        tmpsrv->servername_list_tail->next=NULL;
        /* always negotiate a new session on renegotiation, as the TLS
         * context settings (including access control) may be different */
        section->ssl_options_set|=
            SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
    }

    /* 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_detached(section->protocol_host);
        else if(section->connect_addr.names) /* 'connect' option */
            section->sni=str_dup_detached(section->connect_addr.names->name); /* first hostname */
        if(section->sni) { /* either 'protocolHost' or 'connect' specified */
            tmp_str=strrchr(section->sni, ':');
            if(tmp_str) { /* 'host:port' -> drop ':port' */
                *tmp_str='\0';
            } else { /* 'port' -> default to 'localhost' */
                str_free(section->sni);
                section->sni=str_dup_detached("localhost");
            }
        }
    }
    return NULL;
}
NOEXPORT char *sni_init(SERVICE_OPTIONS *section) {
    char *tmp_str;
    SERVICE_OPTIONS *tmpsrv;

     
    if(!section->option.client && section->sni) {
        tmp_str=strchr(section->sni, ':');
        if(!tmp_str)
            return "Invalid SNI parameter format";
        *tmp_str++='\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_detached(sizeof(SERVERNAME_LIST));
            tmpsrv->servername_list_tail=tmpsrv->servername_list_tail->next;
        } else {  
            tmpsrv->servername_list_head=
                tmpsrv->servername_list_tail=
                str_alloc_detached(sizeof(SERVERNAME_LIST));
            tmpsrv->ssl_options_set|=
                SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
        }
         
        service_up_ref(section);
        tmpsrv->servername_list_tail->servername=str_dup_detached(tmp_str);
        tmpsrv->servername_list_tail->opt=section;
        tmpsrv->servername_list_tail->next=NULL;
         
        section->ssl_options_set|=
            SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
    }

     
    if(section->option.client && !section->sni) {
         
        if(section->protocol_host)  
            section->sni=str_dup_detached(section->protocol_host);
        else if(section->connect_addr.names)  
            section->sni=str_dup_detached(section->connect_addr.names->name);  
        if(section->sni) {  
            tmp_str=strrchr(section->sni, ':');
            if(tmp_str) {  
                *tmp_str='\0';
            } else {  
                str_free(section->sni);
                section->sni=str_dup_detached("localhost");
            }
        }
    }
    return NULL;
}