+ /* If this ClientHello extension was unhandled and this is
+ * a nonresumed connection, check whether the extension is a
+ * custom TLS Extension (has a custom_srv_ext_record), and if
+ * so call the callback and record the extension number so that
+ * an appropriate ServerHello may be later returned.
+ */
+ else if (!s->hit && s->ctx->custom_srv_ext_records_count)
+ {
+ custom_srv_ext_record *record;
+
+ for (i=0; i < s->ctx->custom_srv_ext_records_count; i++)
+ {
+ record = &s->ctx->custom_srv_ext_records[i];
+ if (type == record->ext_type)
+ {
+ /* Error on duplicate TLS Extensions */
+ size_t j;
+
+ for (j = 0; j < s->s3->tlsext_custom_types_count; j++)
+ {
+ if (s->s3->tlsext_custom_types[j] == type)
+ {
+ *al = TLS1_AD_DECODE_ERROR;
+ return 0;
+ }
+ }
+
+ /* Callback */
+ if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
+ return 0;
+
+ /* Add the (non-duplicated) entry */
+ s->s3->tlsext_custom_types_count++;
+ s->s3->tlsext_custom_types = OPENSSL_realloc(
+ s->s3->tlsext_custom_types,
+ s->s3->tlsext_custom_types_count*2);
+ if (s->s3->tlsext_custom_types == NULL)
+ {
+ s->s3->tlsext_custom_types = 0;
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->s3->tlsext_custom_types[
+ s->s3->tlsext_custom_types_count-1] = type;
+ }
+ }
+ }
+