Remove instances in libssl of the constant 28 (for size of IPv4 header + UDP)
and instead use the value provided by the underlying BIO. Also provide some new DTLS_CTRLs so that the library user can set the mtu without needing to know this constant. These new DTLS_CTRLs provide the capability to set the link level mtu to be used (i.e. including this IP/UDP overhead). The previous DTLS_CTRLs required the library user to subtract this overhead first. Reviewed-by: Tim Hudson <tjh@openssl.org>
This commit is contained in:
parent
0d3ae34df5
commit
59669b6abf
@ -156,9 +156,9 @@ static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
|
|||||||
static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
|
static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
|
||||||
|
|
||||||
/* XDTLS: figure out the right values */
|
/* XDTLS: figure out the right values */
|
||||||
static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
|
static const unsigned int g_probable_mtu[] = {1500, 512, 256};
|
||||||
|
|
||||||
static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
|
static void dtls1_guess_mtu(SSL *s);
|
||||||
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
|
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
|
||||||
unsigned long frag_len);
|
unsigned long frag_len);
|
||||||
static unsigned char *dtls1_write_message_header(SSL *s,
|
static unsigned char *dtls1_write_message_header(SSL *s,
|
||||||
@ -226,18 +226,24 @@ void dtls1_hm_fragment_free(hm_fragment *frag)
|
|||||||
|
|
||||||
static void dtls1_query_mtu(SSL *s)
|
static void dtls1_query_mtu(SSL *s)
|
||||||
{
|
{
|
||||||
|
if(s->d1->link_mtu)
|
||||||
|
{
|
||||||
|
s->d1->mtu = s->d1->link_mtu-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
|
||||||
|
s->d1->link_mtu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* AHA! Figure out the MTU, and stick to the right size */
|
/* AHA! Figure out the MTU, and stick to the right size */
|
||||||
if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
|
if (s->d1->mtu < dtls1_min_mtu(s) && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
|
||||||
{
|
{
|
||||||
s->d1->mtu =
|
s->d1->mtu =
|
||||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
|
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
|
||||||
|
|
||||||
/* I've seen the kernel return bogus numbers when it doesn't know
|
/* I've seen the kernel return bogus numbers when it doesn't know
|
||||||
* (initial write), so just make sure we have a reasonable number */
|
* (initial write), so just make sure we have a reasonable number */
|
||||||
if (s->d1->mtu < dtls1_min_mtu())
|
if (s->d1->mtu < dtls1_min_mtu(s))
|
||||||
{
|
{
|
||||||
s->d1->mtu = 0;
|
s->d1->mtu = 0;
|
||||||
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
|
dtls1_guess_mtu(s);
|
||||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
|
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
|
||||||
s->d1->mtu, NULL);
|
s->d1->mtu, NULL);
|
||||||
}
|
}
|
||||||
@ -275,7 +281,7 @@ int dtls1_do_write(SSL *s, int type)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */
|
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something reasonable now */
|
||||||
|
|
||||||
if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
|
if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
|
||||||
OPENSSL_assert(s->init_num ==
|
OPENSSL_assert(s->init_num ==
|
||||||
@ -1300,25 +1306,39 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
dtls1_min_mtu(void)
|
dtls1_link_min_mtu(void)
|
||||||
{
|
{
|
||||||
return (g_probable_mtu[(sizeof(g_probable_mtu) /
|
return (g_probable_mtu[(sizeof(g_probable_mtu) /
|
||||||
sizeof(g_probable_mtu[0])) - 1]);
|
sizeof(g_probable_mtu[0])) - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
unsigned int
|
||||||
dtls1_guess_mtu(unsigned int curr_mtu)
|
dtls1_min_mtu(SSL *s)
|
||||||
{
|
{
|
||||||
|
return dtls1_link_min_mtu()-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dtls1_guess_mtu(SSL *s)
|
||||||
|
{
|
||||||
|
unsigned int curr_mtu;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
unsigned int mtu_ovr;
|
||||||
|
|
||||||
|
curr_mtu = s->d1->mtu;
|
||||||
|
mtu_ovr = BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
|
||||||
|
|
||||||
if ( curr_mtu == 0 )
|
if ( curr_mtu == 0 )
|
||||||
return g_probable_mtu[0] ;
|
{
|
||||||
|
curr_mtu = g_probable_mtu[0] - mtu_ovr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
|
for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
|
||||||
if ( curr_mtu > g_probable_mtu[i])
|
if ( curr_mtu > g_probable_mtu[i] - mtu_ovr)
|
||||||
return g_probable_mtu[i];
|
return g_probable_mtu[i] - mtu_ovr;
|
||||||
|
}
|
||||||
return curr_mtu;
|
s->d1->mtu = curr_mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
25
ssl/d1_lib.c
25
ssl/d1_lib.c
@ -139,6 +139,9 @@ int dtls1_new(SSL *s)
|
|||||||
d1->cookie_len = sizeof(s->d1->cookie);
|
d1->cookie_len = sizeof(s->d1->cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d1->link_mtu = 0;
|
||||||
|
d1->mtu = 0;
|
||||||
|
|
||||||
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
|
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
|
||||||
|| ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
|
|| ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
|
||||||
{
|
{
|
||||||
@ -234,6 +237,7 @@ void dtls1_clear(SSL *s)
|
|||||||
pqueue sent_messages;
|
pqueue sent_messages;
|
||||||
pqueue buffered_app_data;
|
pqueue buffered_app_data;
|
||||||
unsigned int mtu;
|
unsigned int mtu;
|
||||||
|
unsigned int link_mtu;
|
||||||
|
|
||||||
if (s->d1)
|
if (s->d1)
|
||||||
{
|
{
|
||||||
@ -243,6 +247,7 @@ void dtls1_clear(SSL *s)
|
|||||||
sent_messages = s->d1->sent_messages;
|
sent_messages = s->d1->sent_messages;
|
||||||
buffered_app_data = s->d1->buffered_app_data.q;
|
buffered_app_data = s->d1->buffered_app_data.q;
|
||||||
mtu = s->d1->mtu;
|
mtu = s->d1->mtu;
|
||||||
|
link_mtu = s->d1->link_mtu;
|
||||||
|
|
||||||
dtls1_clear_queues(s);
|
dtls1_clear_queues(s);
|
||||||
|
|
||||||
@ -256,6 +261,7 @@ void dtls1_clear(SSL *s)
|
|||||||
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
|
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
|
||||||
{
|
{
|
||||||
s->d1->mtu = mtu;
|
s->d1->mtu = mtu;
|
||||||
|
s->d1->link_mtu = link_mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->d1->unprocessed_rcds.q = unprocessed_rcds;
|
s->d1->unprocessed_rcds.q = unprocessed_rcds;
|
||||||
@ -312,6 +318,25 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
|
|||||||
}
|
}
|
||||||
return 0; /* Unexpected state; fail closed. */
|
return 0; /* Unexpected state; fail closed. */
|
||||||
|
|
||||||
|
/* Just one protocol version is supported so far;
|
||||||
|
* fail closed if the version is not as expected. */
|
||||||
|
return s->version == DTLS_MAX_VERSION;
|
||||||
|
case DTLS_CTRL_SET_LINK_MTU:
|
||||||
|
if (larg < (long)dtls1_link_min_mtu())
|
||||||
|
return 0;
|
||||||
|
s->d1->link_mtu = larg;
|
||||||
|
return 1;
|
||||||
|
case DTLS_CTRL_GET_LINK_MIN_MTU:
|
||||||
|
return (long)dtls1_link_min_mtu();
|
||||||
|
case SSL_CTRL_SET_MTU:
|
||||||
|
/*
|
||||||
|
* We may not have a BIO set yet so can't call dtls1_min_mtu()
|
||||||
|
* We'll have to make do with dtls1_link_min_mtu() and max overhead
|
||||||
|
*/
|
||||||
|
if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
|
||||||
|
return 0;
|
||||||
|
s->d1->mtu = larg;
|
||||||
|
return larg;
|
||||||
default:
|
default:
|
||||||
ret = ssl3_ctrl(s, cmd, larg, parg);
|
ret = ssl3_ctrl(s, cmd, larg, parg);
|
||||||
break;
|
break;
|
||||||
|
@ -121,6 +121,9 @@ extern "C" {
|
|||||||
#define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP"
|
#define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
|
||||||
|
#define DTLS1_MAX_MTU_OVERHEAD 48
|
||||||
|
|
||||||
typedef struct dtls1_bitmap_st
|
typedef struct dtls1_bitmap_st
|
||||||
{
|
{
|
||||||
unsigned long map; /* track 32 packets on 32-bit systems
|
unsigned long map; /* track 32 packets on 32-bit systems
|
||||||
@ -235,6 +238,7 @@ typedef struct dtls1_state_st
|
|||||||
/* Is set when listening for new connections with dtls1_listen() */
|
/* Is set when listening for new connections with dtls1_listen() */
|
||||||
unsigned int listen;
|
unsigned int listen;
|
||||||
|
|
||||||
|
unsigned int link_mtu; /* max on-the-wire DTLS packet size */
|
||||||
unsigned int mtu; /* max DTLS packet size */
|
unsigned int mtu; /* max DTLS packet size */
|
||||||
|
|
||||||
struct hm_header_st w_msg_hdr;
|
struct hm_header_st w_msg_hdr;
|
||||||
|
@ -787,6 +787,10 @@ struct ssl_session_st
|
|||||||
SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
|
SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
|
||||||
#define SSL_set_mtu(ssl, mtu) \
|
#define SSL_set_mtu(ssl, mtu) \
|
||||||
SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
|
SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
|
||||||
|
#define DTLS_set_link_mtu(ssl, mtu) \
|
||||||
|
SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
|
||||||
|
#define DTLS_get_link_min_mtu(ssl) \
|
||||||
|
SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
|
||||||
|
|
||||||
#define SSL_get_secure_renegotiation_support(ssl) \
|
#define SSL_get_secure_renegotiation_support(ssl) \
|
||||||
SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
|
SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
|
||||||
@ -1844,6 +1848,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
|||||||
|
|
||||||
#define SSL_CTRL_SET_DH_AUTO 118
|
#define SSL_CTRL_SET_DH_AUTO 118
|
||||||
#define SSL_CTRL_CHECK_PROTO_VERSION 119
|
#define SSL_CTRL_CHECK_PROTO_VERSION 119
|
||||||
|
#define DTLS_CTRL_SET_LINK_MTU 120
|
||||||
|
#define DTLS_CTRL_GET_LINK_MIN_MTU 121
|
||||||
|
|
||||||
|
|
||||||
#define SSL_CERT_SET_FIRST 1
|
#define SSL_CERT_SET_FIRST 1
|
||||||
|
@ -1129,18 +1129,6 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
|
|||||||
l=s->max_cert_list;
|
l=s->max_cert_list;
|
||||||
s->max_cert_list=larg;
|
s->max_cert_list=larg;
|
||||||
return(l);
|
return(l);
|
||||||
case SSL_CTRL_SET_MTU:
|
|
||||||
#ifndef OPENSSL_NO_DTLS1
|
|
||||||
if (larg < (long)dtls1_min_mtu())
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (SSL_IS_DTLS(s))
|
|
||||||
{
|
|
||||||
s->d1->mtu = larg;
|
|
||||||
return larg;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
|
case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
|
||||||
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
|
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1218,7 +1218,8 @@ void dtls1_stop_timer(SSL *s);
|
|||||||
int dtls1_is_timer_expired(SSL *s);
|
int dtls1_is_timer_expired(SSL *s);
|
||||||
void dtls1_double_timeout(SSL *s);
|
void dtls1_double_timeout(SSL *s);
|
||||||
int dtls1_send_newsession_ticket(SSL *s);
|
int dtls1_send_newsession_ticket(SSL *s);
|
||||||
unsigned int dtls1_min_mtu(void);
|
unsigned int dtls1_min_mtu(SSL *s);
|
||||||
|
unsigned int dtls1_link_min_mtu(void);
|
||||||
void dtls1_hm_fragment_free(hm_fragment *frag);
|
void dtls1_hm_fragment_free(hm_fragment *frag);
|
||||||
|
|
||||||
/* some client-only functions */
|
/* some client-only functions */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user