#include <sys/time.h>
#undef time //needed because HAVE_AV_CONFIG_H is defined on top
#include <time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#include <signal.h>
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
+#include "network.h"
#include "version.h"
#include "ffserver.h"
#include "random.h"
float avg_frame_size; /* frame size averraged over last frames with exponential mean */
} FeedData;
-struct sockaddr_in my_http_addr;
-struct sockaddr_in my_rtsp_addr;
+static struct sockaddr_in my_http_addr;
+static struct sockaddr_in my_rtsp_addr;
static char logfilename[1024];
static HTTPContext *first_http_ctx;
closesocket(server_fd);
return -1;
}
- fcntl(server_fd, F_SETFL, O_NONBLOCK);
+ ff_socket_nonblock(server_fd, 1);
return server_fd;
}
second to handle timeouts */
do {
ret = poll(poll_table, poll_entry - poll_table, delay);
- if (ret < 0 && errno != EAGAIN && errno != EINTR)
+ if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR))
return -1;
} while (ret < 0);
&len);
if (fd < 0)
return;
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ ff_socket_nonblock(fd, 1);
/* XXX: should output a warning page when coming
close to the connection limit */
read_loop:
len = recv(c->fd, c->buffer_ptr, 1, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR)
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR))
return -1;
} else if (len == 0) {
return -1;
return 0;
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
av_freep(&c->pb_buffer);
return -1;
return 0;
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
av_freep(&c->pb_buffer);
return -1;
len = send(c->fd, c->packet_buffer_ptr,
c->packet_buffer_end - c->packet_buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
av_freep(&c->packet_buffer);
return -1;
enum IPAddressAction last_action = IP_DENY;
IPAddressACL *acl;
struct in_addr *src = &c->from_addr.sin_addr;
- unsigned long src_addr = ntohl(src->s_addr);
+ unsigned long src_addr = src->s_addr;
for (acl = stream->acl; acl; acl = acl->next) {
if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr) {
/* TCP data output */
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
return -1;
} else {
len = recv(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
goto fail;
}
dest_addr = rtp_c->from_addr;
dest_addr.sin_port = htons(th->client_port_min);
- /* add transport option if needed */
- if (ff_rtsp_callback) {
- setup.ipaddr = ntohl(dest_addr.sin_addr.s_addr);
- if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id,
- (char *)&setup, sizeof(setup),
- stream->rtsp_option) < 0) {
- rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
- return;
- }
- dest_addr.sin_addr.s_addr = htonl(setup.ipaddr);
- }
-
/* setup stream */
if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPHeader *h)
{
HTTPContext *rtp_c;
+ char session_id[32];
rtp_c = find_rtp_session_with_url(url, h->session_id);
if (!rtp_c) {
return;
}
+ pstrcpy(session_id, sizeof(session_id), rtp_c->session_id);
+
/* abort the session */
close_connection(rtp_c);
- if (ff_rtsp_callback) {
- ff_rtsp_callback(RTSP_ACTION_SERVER_TEARDOWN, rtp_c->session_id,
- NULL, 0,
- rtp_c->stream->rtsp_option);
- }
-
/* now everything is OK, so we can send the connection parameters */
rtsp_reply_header(c, RTSP_STATUS_OK);
/* session ID */
- url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ url_fprintf(c->pb, "Session: %s\r\n", session_id);
url_fprintf(c->pb, "\r\n");
}
c->stream->feed->streams[c->stream->feed_streams[stream_index]],
sizeof(AVStream));
}
+ st->priv_data = NULL;
/* build destination RTP address */
ipaddr = inet_ntoa(dest_addr->sin_addr);
if (!strcasecmp(cmd, "Port")) {
get_arg(arg, sizeof(arg), &p);
- my_http_addr.sin_port = htons (atoi(arg));
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ fprintf(stderr, "%s:%d: Invalid port: %s\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ my_http_addr.sin_port = htons(val);
} else if (!strcasecmp(cmd, "BindAddress")) {
get_arg(arg, sizeof(arg), &p);
- if (!inet_aton(arg, &my_http_addr.sin_addr)) {
- fprintf(stderr, "%s:%d: Invalid IP address: %s\n",
+ if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
+ fprintf(stderr, "%s:%d: Invalid host/IP address: %s\n",
filename, line_num, arg);
errors++;
}
ffserver_daemon = 0;
} else if (!strcasecmp(cmd, "RTSPPort")) {
get_arg(arg, sizeof(arg), &p);
- my_rtsp_addr.sin_port = htons (atoi(arg));
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ fprintf(stderr, "%s:%d: Invalid port: %s\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ my_rtsp_addr.sin_port = htons(atoi(arg));
} else if (!strcasecmp(cmd, "RTSPBindAddress")) {
get_arg(arg, sizeof(arg), &p);
- if (!inet_aton(arg, &my_rtsp_addr.sin_addr)) {
- fprintf(stderr, "%s:%d: Invalid IP address: %s\n",
+ if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
+ fprintf(stderr, "%s:%d: Invalid host/IP address: %s\n",
filename, line_num, arg);
errors++;
}
feed->child_argv = (char **) av_mallocz(64 * sizeof(char *));
for (i = 0; i < 62; i++) {
- char argbuf[256];
-
- get_arg(argbuf, sizeof(argbuf), &p);
- if (!argbuf[0])
+ get_arg(arg, sizeof(arg), &p);
+ if (!arg[0])
break;
- feed->child_argv[i] = av_malloc(strlen(argbuf) + 1);
- strcpy(feed->child_argv[i], argbuf);
+ feed->child_argv[i] = av_strdup(arg);
}
feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
fprintf(stderr, "%s:%d: No corresponding <Feed> for </Feed>\n",
filename, line_num);
errors++;
-#if 0
- } else {
- /* Make sure that we start out clean */
- if (unlink(feed->feed_filename) < 0
- && errno != ENOENT) {
- fprintf(stderr, "%s:%d: Unable to clean old feed file '%s': %s\n",
- filename, line_num, feed->feed_filename, strerror(errno));
- errors++;
- }
-#endif
}
feed = NULL;
} else if (!strcasecmp(cmd, "<Stream")) {
video_id = stream->fmt->video_codec;
}
} else if (!strcasecmp(cmd, "InputFormat")) {
+ get_arg(arg, sizeof(arg), &p);
stream->ifmt = av_find_input_format(arg);
if (!stream->ifmt) {
fprintf(stderr, "%s:%d: Unknown input format: %s\n",
audio_id = CODEC_ID_NONE;
} else if (!strcasecmp(cmd, "ACL")) {
IPAddressACL acl;
- struct hostent *he;
get_arg(arg, sizeof(arg), &p);
if (strcasecmp(arg, "allow") == 0) {
get_arg(arg, sizeof(arg), &p);
- he = gethostbyname(arg);
- if (!he) {
+ if (resolve_host(&acl.first, arg) != 0) {
fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
filename, line_num, arg);
errors++;
} else {
- /* Only take the first */
- acl.first.s_addr = ntohl(((struct in_addr *) he->h_addr_list[0])->s_addr);
acl.last = acl.first;
}
get_arg(arg, sizeof(arg), &p);
if (arg[0]) {
- he = gethostbyname(arg);
- if (!he) {
+ if (resolve_host(&acl.last, arg) != 0) {
fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
filename, line_num, arg);
errors++;
- } else {
- /* Only take the first */
- acl.last.s_addr = ntohl(((struct in_addr *) he->h_addr_list[0])->s_addr);
}
}
} else if (!strcasecmp(cmd, "MulticastAddress")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
- if (!inet_aton(arg, &stream->multicast_ip)) {
- fprintf(stderr, "%s:%d: Invalid IP address: %s\n",
+ if (resolve_host(&stream->multicast_ip, arg) != 0) {
+ fprintf(stderr, "%s:%d: Invalid host/IP address: %s\n",
filename, line_num, arg);
errors++;
}