]> git.sesse.net Git - ffmpeg/blobdiff - ffserver.c
typo
[ffmpeg] / ffserver.c
index 063ac5a028c2c35514cafa168baf7871a127ce66..8f9bba6b49c9cc610ab4519eed21d2948d4a9591 100644 (file)
 #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"
@@ -234,8 +230,8 @@ typedef struct FeedData {
     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;
@@ -444,7 +440,7 @@ static int socket_open_listen(struct sockaddr_in *my_addr)
         closesocket(server_fd);
         return -1;
     }
-    fcntl(server_fd, F_SETFL, O_NONBLOCK);
+    ff_socket_nonblock(server_fd, 1);
 
     return server_fd;
 }
@@ -592,9 +588,10 @@ static int http_server(void)
            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);
+        } while (ret < 0);
 
         cur_time = av_gettime() / 1000;
 
@@ -652,7 +649,7 @@ static void new_connection(int server_fd, int is_rtsp)
                 &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 */
@@ -795,7 +792,8 @@ static int handle_connection(HTTPContext *c)
     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;
@@ -830,7 +828,8 @@ static int handle_connection(HTTPContext *c)
             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;
@@ -900,7 +899,8 @@ static int handle_connection(HTTPContext *c)
             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;
@@ -926,7 +926,8 @@ static int handle_connection(HTTPContext *c)
         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;
@@ -1120,7 +1121,7 @@ static int validate_acl(FFStream *stream, HTTPContext *c)
     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) {
@@ -2337,7 +2338,8 @@ static int http_send_data(HTTPContext *c)
                 /* 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 {
@@ -2394,7 +2396,8 @@ static int http_receive_data(HTTPContext *c)
 
         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;
             }
@@ -2508,9 +2511,39 @@ static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
     char buf2[32];
 
     switch(error_number) {
-#define DEF(n, c, s) case c: str = s; break;
-#include "rtspcodes.h"
-#undef DEF
+    case RTSP_STATUS_OK:
+        str = "OK";
+        break;
+    case RTSP_STATUS_METHOD:
+        str = "Method Not Allowed";
+        break;
+    case RTSP_STATUS_BANDWIDTH:
+        str = "Not Enough Bandwidth";
+        break;
+    case RTSP_STATUS_SESSION:
+        str = "Session Not Found";
+        break;
+    case RTSP_STATUS_STATE:
+        str = "Method Not Valid in This State";
+        break;
+    case RTSP_STATUS_AGGREGATE:
+        str = "Aggregate operation not allowed";
+        break;
+    case RTSP_STATUS_ONLY_AGGREGATE:
+        str = "Only aggregate operation allowed";
+        break;
+    case RTSP_STATUS_TRANSPORT:
+        str = "Unsupported transport";
+        break;
+    case RTSP_STATUS_INTERNAL:
+        str = "Internal Server Error";
+        break;
+    case RTSP_STATUS_SERVICE:
+        str = "Service Unavailable";
+        break;
+    case RTSP_STATUS_VERSION:
+        str = "RTSP Version not supported";
+        break;
     default:
         str = "Unknown Error";
         break;
@@ -2902,18 +2935,6 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
     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);
@@ -3044,6 +3065,7 @@ static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h)
 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) {
@@ -3051,19 +3073,15 @@ static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPHeader *h)
         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");
 }
 
@@ -3170,6 +3188,7 @@ static int rtp_new_av_stream(HTTPContext *c,
                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);
@@ -3798,11 +3817,17 @@ static int parse_ffconfig(const char *filename)
 
         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++;
             }
@@ -3810,11 +3835,17 @@ static int parse_ffconfig(const char *filename)
             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++;
             }
@@ -3875,14 +3906,11 @@ static int parse_ffconfig(const char *filename)
                 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));
@@ -3941,16 +3969,6 @@ static int parse_ffconfig(const char *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")) {
@@ -4019,6 +4037,7 @@ static int parse_ffconfig(const char *filename)
                 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",
@@ -4252,7 +4271,6 @@ static int parse_ffconfig(const char *filename)
             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) {
@@ -4267,28 +4285,21 @@ static int parse_ffconfig(const char *filename)
 
             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);
                 }
             }
 
@@ -4325,8 +4336,8 @@ static int parse_ffconfig(const char *filename)
         } 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++;
                 }