diff options
-rw-r--r-- | channels/chan_sip.c | 3 | ||||
-rw-r--r-- | include/asterisk/utils.h | 15 | ||||
-rw-r--r-- | netsock.c | 2 | ||||
-rw-r--r-- | utils.c | 11 |
4 files changed, 31 insertions, 0 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index b8fae44bc..4e6b105b4 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -12966,10 +12966,13 @@ static int reload_config(void) } else { /* Allow SIP clients on the same host to access us: */ const int reuseFlag = 1; + setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseFlag, sizeof reuseFlag); + ast_enable_packet_fragmentation(sipsock); + if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index b6b85df4e..0f1df4003 100644 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -235,4 +235,19 @@ char *ast_process_quotes_and_slashes(char *start, char find, char replace_with); int getloadavg(double *list, int nelem); #endif +/*! + \brief Disable PMTU discovery on a socket + \param sock The socket to manipulate + \return Nothing + + On Linux, UDP sockets default to sending packets with the Dont Fragment (DF) + bit set. This is supposedly done to allow the application to do PMTU + discovery, but Asterisk does not do this. + + Because of this, UDP packets sent by Asterisk that are larger than the MTU + of any hop in the path will be lost. This function can be called on a socket + to ensure that the DF bit will not be set. + */ +void ast_enable_packet_fragmentation(int sock); + #endif /* _ASTERISK_UTILS_H */ @@ -147,6 +147,8 @@ struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct i if (setsockopt(netsocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); + ast_enable_packet_fragmentation(netsocket); + ns = malloc(sizeof(struct ast_netsock)); if (ns) { /* Establish I/O callback for socket read */ @@ -895,3 +895,14 @@ char *ast_process_quotes_and_slashes(char *start, char find, char replace_with) *dataPut = 0; return dataPut; } + +void ast_enable_packet_fragmentation(int sock) +{ +#ifdef __linux__ + int val = IP_PMTUDISC_DONT; + + if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) + ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n"); +#endif +} + |