obs-outputs: Add output error messages for RTMP

This commit is contained in:
Richard Stanway
2017-05-15 12:05:44 +02:00
parent 50f8a066b9
commit 92a258690e
5 changed files with 114 additions and 16 deletions
@@ -3,3 +3,11 @@ RTMPStream.DropThreshold="Drop Threshold (milliseconds)"
FLVOutput="FLV File Output"
FLVOutput.FilePath="File Path"
Default="Default"
ConnectionTimedOut="The connection timed out. Make sure you've configured a valid streaming service and no firewall is blocking the connection."
PermissionDenied="The connection was blocked. Check your firewall / anti-virus settings to make sure OBS is allowed full internet access."
ConnectionAborted="The connection was aborted. This usually indicates internet connection problems between you and the streaming service."
ConnectionReset="The connection was reset by the peer. This usually indicates internet connection problems between you and the streaming service."
HostNotFound="Hostname not found. Make sure you entered a valid streaming server and your internet connection / DNS are working correctly."
NoData="Hostname found, but no data of the requested type. This can occur if you have bound to an IPv6 address and your streaming service only has IPv4 addresses (see Settings / Advanced)."
AddressNotAvailable="Address not available. You may have tried to bind to an invalid IP address (see Settings / Advanced)."
+37 -15
View File
@@ -652,7 +652,7 @@ int RTMP_AddStream(RTMP *r, const char *playpath)
}
static int
add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host, int port, socklen_t addrlen_hint)
add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host, int port, socklen_t addrlen_hint, int *socket_error)
{
char *hostname;
int ret = TRUE;
@@ -693,6 +693,7 @@ add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host,
#define gai_strerrorA gai_strerror
#endif
RTMP_Log(RTMP_LOGERROR, "Could not resolve %s: %s (%d)", hostname, gai_strerrorA(GetSockError()), GetSockError());
*socket_error = GetSockError();
ret = FALSE;
goto finish;
}
@@ -708,23 +709,30 @@ add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host,
}
}
if (!*addrlen)
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (!*addrlen)
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (ptr->ai_family == AF_INET6 && (!addrlen_hint || ptr->ai_addrlen == addrlen_hint))
{
memcpy(service, ptr->ai_addr, ptr->ai_addrlen);
*addrlen = (socklen_t)ptr->ai_addrlen;
break;
}
}
}
{
memcpy(service, ptr->ai_addr, ptr->ai_addrlen);
*addrlen = (socklen_t)ptr->ai_addrlen;
break;
}
}
}
freeaddrinfo(result);
if (service->ss_family == AF_UNSPEC || *addrlen == 0)
{
// since we're handling multiple addresses internally, fake the correct error response
#ifdef _WIN32
*socket_error = WSANO_DATA;
#else
*socket_error = ENODATA;
#endif
RTMP_Log(RTMP_LOGERROR, "Could not resolve server '%s': no valid address found", hostname);
ret = FALSE;
goto finish;
@@ -770,6 +778,7 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen)
int err = GetSockError();
RTMP_Log(RTMP_LOGERROR, "%s, failed to bind socket: %s (%d)",
__FUNCTION__, socketerror(err), err);
r->last_error_code = err;
RTMP_Close(r);
return FALSE;
}
@@ -789,6 +798,7 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen)
else
RTMP_Log(RTMP_LOGERROR, "%s, failed to connect socket: %s (%d)",
__FUNCTION__, socketerror(err), err);
r->last_error_code = err;
RTMP_Close(r);
return FALSE;
}
@@ -912,6 +922,8 @@ RTMP_Connect(RTMP *r, RTMPPacket *cp)
struct sockaddr_storage service;
socklen_t addrlen = 0;
socklen_t addrlen_hint = 0;
int socket_error = 0;
if (!r->Link.hostname.av_len)
return FALSE;
@@ -920,6 +932,7 @@ RTMP_Connect(RTMP *r, RTMPPacket *cp)
h = gethostbyname("localhost");
if (!h && GetLastError() == WSAHOST_NOT_FOUND)
{
r->last_error_code = WSAHOST_NOT_FOUND;
RTMP_Log(RTMP_LOGERROR, "RTMP_Connect: Connection test failed. This error is likely caused by Comodo Internet Security running OBS in sandbox mode. Please add OBS to the Comodo automatic sandbox exclusion list, restart OBS and try again (11001).");
return FALSE;
}
@@ -933,14 +946,20 @@ RTMP_Connect(RTMP *r, RTMPPacket *cp)
if (r->Link.socksport)
{
/* Connect via SOCKS */
if (!add_addr_info(&service, &addrlen, &r->Link.sockshost, r->Link.socksport, addrlen_hint))
if (!add_addr_info(&service, &addrlen, &r->Link.sockshost, r->Link.socksport, addrlen_hint, &socket_error))
{
r->last_error_code = socket_error;
return FALSE;
}
}
else
{
/* Connect directly */
if (!add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port, addrlen_hint))
if (!add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port, addrlen_hint, &socket_error))
{
r->last_error_code = socket_error;
return FALSE;
}
}
if (!RTMP_Connect0(r, (struct sockaddr *)&service, addrlen))
@@ -957,9 +976,10 @@ SocksNegotiate(RTMP *r)
unsigned long addr;
struct sockaddr_storage service;
socklen_t addrlen = 0;
int socket_error = 0;
memset(&service, 0, sizeof(service));
add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port, 0);
add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port, 0, &socket_error);
// not doing IPv6 socks
if (service.ss_family == AF_INET6)
@@ -1442,6 +1462,8 @@ WriteN(RTMP *r, const char *buffer, int n)
if (sockerr == EINTR && !RTMP_ctrlC)
continue;
r->last_error_code = sockerr;
RTMP_Close(r);
n = 1;
break;
+1
View File
@@ -325,6 +325,7 @@ extern "C"
RTMPSockBuf m_sb;
RTMP_LNK Link;
int connect_time_ms;
int last_error_code;
} RTMP;
int RTMP_ParseURL(const char *url, int *protocol, AVal *host,
+66 -1
View File
@@ -378,6 +378,64 @@ static inline bool can_shutdown_stream(struct rtmp_stream *stream,
return timeout || packet->sys_dts_usec >= (int64_t)stream->stop_ts;
}
static void set_output_error(struct rtmp_stream *stream)
{
const char *msg = NULL;
#ifdef _WIN32
switch (stream->rtmp.last_error_code)
{
case WSAETIMEDOUT:
msg = obs_module_text("ConnectionTimedOut");
break;
case WSAEACCES:
msg = obs_module_text("PermissionDenied");
break;
case WSAECONNABORTED:
msg = obs_module_text("ConnectionAborted");
break;
case WSAECONNRESET:
msg = obs_module_text("ConnectionReset");
break;
case WSAHOST_NOT_FOUND:
msg = obs_module_text("HostNotFound");
break;
case WSANO_DATA:
msg = obs_module_text("NoData");
break;
case WSAEADDRNOTAVAIL:
msg = obs_module_text("AddressNotAvailable");
break;
}
#else
switch (stream->rtmp.last_error_code)
{
case ETIMEDOUT:
msg = obs_module_text("ConnectionTimedOut");
break;
case EACCES:
msg = obs_module_text("PermissionDenied");
break;
case ECONNABORTED:
msg = obs_module_text("ConnectionAborted");
break;
case ECONNRESET:
msg = obs_module_text("ConnectionReset");
break;
case HOST_NOT_FOUND:
msg = obs_module_text("HostNotFound");
break;
case NO_DATA:
msg = obs_module_text("NoData");
break;
case EADDRNOTAVAIL:
msg = obs_module_text("AddressNotAvailable");
break;
}
#endif
obs_output_set_last_error(stream->output, msg);
}
static void *send_thread(void *data)
{
struct rtmp_stream *stream = data;
@@ -428,6 +486,7 @@ static void *send_thread(void *data)
stream->rtmp.m_bCustomSend = false;
}
set_output_error(stream);
RTMP_Close(&stream->rtmp);
if (!stopping(stream)) {
@@ -571,8 +630,10 @@ static int init_send(struct rtmp_stream *stream)
int one = 1;
#ifdef _WIN32
if (ioctlsocket(stream->rtmp.m_sb.sb_socket, FIONBIO, &one)) {
stream->rtmp.last_error_code = WSAGetLastError();
#else
if (ioctl(stream->rtmp.m_sb.sb_socket, FIONBIO, &one)) {
stream->rtmp.last_error_code = errno;
#endif
warn("Failed to set non-blocking socket");
return OBS_OUTPUT_ERROR;
@@ -644,6 +705,7 @@ static int init_send(struct rtmp_stream *stream)
if (!send_meta_data(stream, idx++, &next)) {
warn("Disconnected while attempting to connect to "
"server.");
set_output_error(stream);
return OBS_OUTPUT_DISCONNECTED;
}
}
@@ -767,8 +829,11 @@ static int try_connect(struct rtmp_stream *stream)
win32_log_interface_type(stream);
#endif
if (!RTMP_Connect(&stream->rtmp, NULL))
if (!RTMP_Connect(&stream->rtmp, NULL)) {
set_output_error(stream);
return OBS_OUTPUT_CONNECT_FAILED;
}
if (!RTMP_ConnectStream(&stream->rtmp, 0))
return OBS_OUTPUT_INVALID_STREAM;
+2
View File
@@ -81,6 +81,7 @@ static bool socket_event(struct rtmp_stream *stream, bool *can_write,
"Socket error, recv() returned "
"%d, GetLastError() %d",
ret, err_code);
stream->rtmp.last_error_code = err_code;
fatal_sock_shutdown(stream);
return false;
}
@@ -215,6 +216,7 @@ static enum data_ret write_data(struct rtmp_stream *stream, bool *can_write,
ret, err_code);
pthread_mutex_unlock(&stream->write_buf_mutex);
stream->rtmp.last_error_code = err_code;
fatal_sock_shutdown(stream);
return RET_FATAL;
}