Browse code

* Make asf streaming work again. Now uses the output format asf_stream. * Add ip address based acls for streams. I recommend adding ACL entries for all feeds to control who can submit stuff. You might also want to consider who can get to your status page. * Make logging work again if customlog == "-"

Originally committed as revision 821 to svn://svn.ffmpeg.org/ffmpeg/trunk

Philip Gladstone authored on 2002/07/27 12:03:04
Showing 1 changed files
... ...
@@ -154,6 +154,18 @@ enum StreamType {
154 154
     STREAM_TYPE_REDIRECT,
155 155
 };
156 156
 
157
+enum IPAddressAction {
158
+    IP_ALLOW = 1,
159
+    IP_DENY,
160
+};
161
+
162
+typedef struct IPAddressACL {
163
+    struct IPAddressACL *next;
164
+    enum IPAddressAction action;
165
+    struct in_addr first;
166
+    struct in_addr last;
167
+} IPAddressACL;
168
+
157 169
 /* description of each stream of the ffserver.conf file */
158 170
 typedef struct FFStream {
159 171
     enum StreamType stream_type;
... ...
@@ -161,6 +173,7 @@ typedef struct FFStream {
161 161
     struct FFStream *feed;   /* feed we are using (can be null if
162 162
                                 coming from file) */
163 163
     AVOutputFormat *fmt;
164
+    IPAddressACL *acl;
164 165
     int nb_streams;
165 166
     int prebuffer;      /* Number of millseconds early to start */
166 167
     long max_time;      /* Number of milliseconds to run */
... ...
@@ -957,6 +970,23 @@ static void get_word(char *buf, int buf_size, const char **pp)
957 957
     *pp = p;
958 958
 }
959 959
 
960
+static int validate_acl(FFStream *stream, HTTPContext *c)
961
+{
962
+    enum IPAddressAction last_action = IP_DENY;
963
+    IPAddressACL *acl;
964
+    struct in_addr *src = &c->from_addr.sin_addr;
965
+
966
+    for (acl = stream->acl; acl; acl = acl->next) {
967
+        if (src->s_addr >= acl->first.s_addr && src->s_addr <= acl->last.s_addr) {
968
+            return (acl->action == IP_ALLOW) ? 1 : 0;
969
+        }
970
+        last_action = acl->action;
971
+    }
972
+
973
+    /* Nothing matched, so return not the last action */
974
+    return (last_action == IP_DENY) ? 1 : 0;
975
+}
976
+
960 977
 /* parse http request and prepare header */
961 978
 static int http_parse_request(HTTPContext *c)
962 979
 {
... ...
@@ -1077,7 +1107,7 @@ static int http_parse_request(HTTPContext *c)
1077 1077
 
1078 1078
     stream = first_stream;
1079 1079
     while (stream != NULL) {
1080
-        if (!strcmp(stream->filename, filename))
1080
+        if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
1081 1081
             break;
1082 1082
         stream = stream->next;
1083 1083
     }
... ...
@@ -1342,14 +1372,10 @@ static int http_parse_request(HTTPContext *c)
1342 1342
     q += sprintf(q, "Pragma: no-cache\r\n");
1343 1343
 
1344 1344
     /* for asf, we need extra headers */
1345
-    if (!strcmp(c->stream->fmt->name,"asf")) {
1345
+    if (!strcmp(c->stream->fmt->name,"asf_stream")) {
1346 1346
         /* Need to allocate a client id */
1347
-        static int wmp_session;
1348 1347
 
1349
-        if (!wmp_session)
1350
-            wmp_session = time(0) & 0xffffff;
1351
-
1352
-        c->wmp_client_id = ++wmp_session;
1348
+        c->wmp_client_id = random() & 0x7fffffff;
1353 1349
 
1354 1350
         q += sprintf(q, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
1355 1351
         mime_type = "application/octet-stream"; 
... ...
@@ -1719,6 +1745,12 @@ static int open_input_stream(HTTPContext *c, const char *info)
1719 1719
     if (input_filename[0] == '\0')
1720 1720
         return -1;
1721 1721
 
1722
+#if 0
1723
+    { time_t when = stream_pos / 1000000;
1724
+    http_log("Stream pos = %lld, time=%s", stream_pos, ctime(&when));
1725
+    }
1726
+#endif
1727
+
1722 1728
     /* open stream */
1723 1729
     if (av_open_input_file(&s, input_filename, NULL, buf_size, NULL) < 0) {
1724 1730
         http_log("%s not found", input_filename);
... ...
@@ -3447,7 +3479,7 @@ int parse_ffconfig(const char *filename)
3447 3447
                 q = strrchr(stream->filename, '>');
3448 3448
                 if (*q)
3449 3449
                     *q = '\0';
3450
-                stream->fmt = guess_format(NULL, stream->filename, NULL);
3450
+                stream->fmt = guess_stream_format(NULL, stream->filename, NULL);
3451 3451
                 memset(&audio_enc, 0, sizeof(AVCodecContext));
3452 3452
                 memset(&video_enc, 0, sizeof(AVCodecContext));
3453 3453
                 audio_id = CODEC_ID_NONE;
... ...
@@ -3485,7 +3517,7 @@ int parse_ffconfig(const char *filename)
3485 3485
                 /* jpeg cannot be used here, so use single frame jpeg */
3486 3486
                 if (!strcmp(arg, "jpeg"))
3487 3487
                     strcpy(arg, "singlejpeg");
3488
-                stream->fmt = guess_format(arg, NULL, NULL);
3488
+                stream->fmt = guess_stream_format(arg, NULL, NULL);
3489 3489
                 if (!stream->fmt) {
3490 3490
                     fprintf(stderr, "%s:%d: Unknown Format: %s\n", 
3491 3491
                             filename, line_num, arg);
... ...
@@ -3523,7 +3555,7 @@ int parse_ffconfig(const char *filename)
3523 3523
         } else if (!strcasecmp(cmd, "Preroll")) {
3524 3524
             get_arg(arg, sizeof(arg), &p);
3525 3525
             if (stream) {
3526
-                stream->prebuffer = atoi(arg) * 1000;
3526
+                stream->prebuffer = atof(arg) * 1000;
3527 3527
             }
3528 3528
         } else if (!strcasecmp(cmd, "StartSendOnKey")) {
3529 3529
             if (stream) {
... ...
@@ -3548,7 +3580,7 @@ int parse_ffconfig(const char *filename)
3548 3548
         } else if (!strcasecmp(cmd, "MaxTime")) {
3549 3549
             get_arg(arg, sizeof(arg), &p);
3550 3550
             if (stream) {
3551
-                stream->max_time = atoi(arg) * 1000;
3551
+                stream->max_time = atof(arg) * 1000;
3552 3552
             }
3553 3553
         } else if (!strcasecmp(cmd, "AudioBitRate")) {
3554 3554
             get_arg(arg, sizeof(arg), &p);
... ...
@@ -3630,6 +3662,72 @@ int parse_ffconfig(const char *filename)
3630 3630
             video_id = CODEC_ID_NONE;
3631 3631
         } else if (!strcasecmp(cmd, "NoAudio")) {
3632 3632
             audio_id = CODEC_ID_NONE;
3633
+        } else if (!strcasecmp(cmd, "ACL")) {
3634
+            IPAddressACL acl;
3635
+            struct hostent *he;
3636
+
3637
+            get_arg(arg, sizeof(arg), &p);
3638
+            if (strcasecmp(arg, "allow") == 0) {
3639
+                acl.action = IP_ALLOW;
3640
+            } else if (strcasecmp(arg, "deny") == 0) {
3641
+                acl.action = IP_DENY;
3642
+            } else {
3643
+                fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
3644
+                        filename, line_num, arg);
3645
+                errors++;
3646
+            }
3647
+
3648
+            get_arg(arg, sizeof(arg), &p);
3649
+
3650
+            he = gethostbyname(arg);
3651
+            if (!he) {
3652
+                fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
3653
+                        filename, line_num, arg);
3654
+                errors++;
3655
+            } else {
3656
+                /* Only take the first */
3657
+                acl.first = *(struct in_addr *) he->h_addr_list[0];
3658
+                acl.last = acl.first;
3659
+            }
3660
+
3661
+            get_arg(arg, sizeof(arg), &p);
3662
+
3663
+            if (arg[0]) {
3664
+                he = gethostbyname(arg);
3665
+                if (!he) {
3666
+                    fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
3667
+                            filename, line_num, arg);
3668
+                    errors++;
3669
+                } else {
3670
+                    /* Only take the first */
3671
+                    acl.last = *(struct in_addr *) he->h_addr_list[0];
3672
+                }
3673
+            }
3674
+
3675
+            if (!errors) {
3676
+                IPAddressACL *nacl = (IPAddressACL *) av_mallocz(sizeof(*nacl));
3677
+                IPAddressACL **naclp = 0;
3678
+
3679
+                *nacl = acl;
3680
+                nacl->next = 0;
3681
+
3682
+                if (stream) {
3683
+                    naclp = &stream->acl;
3684
+                } else if (feed) {
3685
+                    naclp = &feed->acl;
3686
+                } else {
3687
+                    fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
3688
+                            filename, line_num);
3689
+                    errors++;
3690
+                }
3691
+
3692
+                if (naclp) {
3693
+                    while (*naclp)
3694
+                        naclp = &(*naclp)->next;
3695
+
3696
+                    *naclp = nacl;
3697
+                }
3698
+            }
3633 3699
         } else if (!strcasecmp(cmd, "RTSPOption")) {
3634 3700
             get_arg(arg, sizeof(arg), &p);
3635 3701
             if (stream) {
... ...
@@ -3830,6 +3928,8 @@ int main(int argc, char **argv)
3830 3830
 
3831 3831
     putenv("http_proxy");               /* Kill the http_proxy */
3832 3832
 
3833
+    srandom(gettime_ms() + (getpid() << 16));
3834
+
3833 3835
     /* address on which the server will handle HTTP connections */
3834 3836
     my_http_addr.sin_family = AF_INET;
3835 3837
     my_http_addr.sin_port = htons (8080);
... ...
@@ -3875,10 +3975,12 @@ int main(int argc, char **argv)
3875 3875
             setsid();
3876 3876
             chdir("/");
3877 3877
             close(0);
3878
-            close(1);
3879
-            close(2);
3880 3878
             open("/dev/null", O_RDWR);
3881
-            dup(0);
3879
+            if (!strcmp(logfilename, "-")) {
3880
+                close(1);
3881
+                dup(0);
3882
+            }
3883
+            close(2);
3882 3884
             dup(0);
3883 3885
         }
3884 3886
     }