char * getlocalip() { // if(localip[0]!=0)return localip; const char *dest = opts.disc_host, *h; int port = 1900; struct sockaddr_in serv; int sock = socket(AF_INET, SOCK_DGRAM, 0); //Socket could not be created if (sock < 0) { LOG("getlocalip: Cannot create socket: %s", strerror(errno)); return localip; } fill_sockaddr(&serv, (char *) dest, port); int err = connect(sock, (const struct sockaddr *) &serv, sizeof(serv)); if (err) { LOG("getlocalip: Error '%s'' during connect", strerror(errno)); memset(localip, 0, sizeof(localip)); } else { h = get_sock_shost(sock); if (h) strcpy(localip, h); } close(sock); return localip; }
int read_rtsp(sockets * s) { char *arg[50]; int cseq, la, i, rlen; char *transport = NULL; int sess_id = 0; char buf[2000]; char tmp_ra[50]; streams *sid = get_sid(s->sid); if (s->buf[0] == 0x24 && s->buf[1] < 2) { if (sid) sid->rtime = s->rtime; int rtsp_len = s->buf[2] * 256 + s->buf[3]; LOG( "Received RTSP over tcp packet (sock_id %d, stream %d, rlen %d) packet len: %d, type %02X %02X discarding %s...", s->id, s->sid, s->rlen, rtsp_len, s->buf[4], s->buf[5], (s->rlen == rtsp_len + 4) ? "complete" : "fragment"); if (s->rlen == rtsp_len + 4) { // we did not receive the entire packet s->rlen = 0; return 0; } } if (s->rlen < 4 || !end_of_header(s->buf + s->rlen - 4)) { if (s->rlen > RBUF - 10) { LOG( "Discarding %d bytes from the socket buffer, request > %d, consider increasing RBUF", s->rlen, RBUF); s->rlen = 0; } LOG( "read_rtsp: read %d bytes from handle %d, sock_id %d, flags %d not ending with \\r\\n\\r\\n", s->rlen, s->sock, s->id, s->flags); if (s->flags & 1) return 0; unsigned char *new_alloc = malloc1(RBUF); memcpy(new_alloc, s->buf, s->rlen); s->buf = new_alloc; s->flags = s->flags | 1; return 0; } rlen = s->rlen; s->rlen = 0; LOG("read RTSP (from handle %d sock_id %d, len: %d, sid %d):\n%s", s->sock, s->id, s->rlen, s->sid, s->buf); if ((s->type != TYPE_HTTP) && (strncasecmp((const char*) s->buf, "GET", 3) == 0)) { http_response(s, 404, NULL, NULL, 0, 0); return 0; } la = split(arg, (char*) s->buf, 50, ' '); cseq = 0; if (la < 2) LOG_AND_RETURN(0, "Most likely not an RTSP packet sock_id: %d sid: %d rlen: %d, dropping ....", s->id, s->sid, rlen); if (s->sid < 0) for (i = 0; i < la; i++) if (strncasecmp("Session:", arg[i], 8) == 0) { sess_id = map_int(header_parameter(arg, i), NULL); s->sid = find_session_id(sess_id); } /* if (s->sid < 0 && strstr(arg[1], "stream=")) // stream= in URL { char *str_id = strstr(arg[1], "stream=") + 7; sess_id = map_intd(str_id, NULL, 0) - 1; if ((sid = get_sid(sess_id))) { s->sid = sid->sid; LOG("Adopting the session id from the stream %d", s->sid); } } */ if (strstr(arg[1], "freq") || strstr(arg[1], "pids")) { sid = (streams *) setup_stream(arg[1], s); } // if(!get_sid(s->sid) && ((strncasecmp (arg[0], "PLAY", 4) == 0) || (strncasecmp (arg[0], "GET", 3) == 0) || (strncasecmp (arg[0], "SETUP", 5) == 0))) // sid = (streams *) setup_stream (arg[1], s); //setup empty stream sid = get_sid(s->sid); if (sid) sid->rtime = s->rtime; if (sess_id) set_session_id(s->sid, sess_id); for (i = 0; i < la; i++) if (strncasecmp("CSeq:", arg[i], 5) == 0) cseq = map_int(header_parameter(arg, i), NULL); else if (strncasecmp("Transport:", arg[i], 9) == 0) { transport = header_parameter(arg, i); if (-1 == decode_transport(s, transport, opts.rrtp, opts.start_rtp)) { http_response(s, 400, NULL, NULL, cseq, 0); return 0; } } else if (strstr(arg[i], "LIVE555")) { if (sid) sid->timeout = 0; } else if (strstr(arg[i], "Lavf")) { if (sid) sid->timeout = 0; } if ((strncasecmp(arg[0], "PLAY", 4) == 0) || (strncasecmp(arg[0], "GET", 3) == 0) || (strncasecmp(arg[0], "SETUP", 5) == 0)) { char ra[100]; int rv; if (!(sid = get_sid(s->sid))) { http_response(s, 454, NULL, NULL, cseq, 0); return 0; } if ((strncasecmp(arg[0], "PLAY", 3) == 0) || (strncasecmp(arg[0], "GET", 3) == 0)) if ((rv = start_play(sid, s)) < 0) { http_response(s, -rv, NULL, NULL, cseq, 0); return 0; } get_socket_rhost(sid->sid, ra, sizeof(ra)); buf[0] = 0; if (transport) { int s_timeout; if (sid->timeout == 1) sid->timeout = opts.timeout_sec; s_timeout = ( (sid->timeout > 20000) ? sid->timeout : opts.timeout_sec) / 1000; switch (sid->type) { case STREAM_RTSP_UDP: if (atoi(ra) < 224) snprintf(buf, sizeof(buf), "Transport: RTP/AVP;unicast;destination=%s;source=%s;client_port=%d-%d;server_port=%d-%d\r\nSession: %010d;timeout=%d\r\ncom.ses.streamID: %d", ra, get_sock_shost(s->sock), get_stream_rport(sid->sid), get_stream_rport(sid->sid) + 1, // opts.start_rtp, opts.start_rtp + 1, get_sock_sport(sid->rsock), get_sock_sport(sid->rtcp), get_session_id(s->sid), s_timeout, sid->sid + 1); else snprintf(buf, sizeof(buf), "Transport: RTP/AVP;multicast;destination=%s;port=%d-%d\r\nSession: %010d;timeout=%d\r\ncom.ses.streamID: %d", ra, get_stream_rport(sid->sid), ntohs (sid->sa.sin_port) + 1, get_session_id(s->sid), s_timeout, sid->sid + 1); break; case STREAM_RTSP_TCP: snprintf(buf, sizeof(buf), "Transport: RTP/AVP/TCP;interleaved=0-1\r\nSession: %010d;timeout=%d\r\ncom.ses.streamID: %d", get_session_id(s->sid), s_timeout, sid->sid + 1); break; } } if (strncasecmp(arg[0], "PLAY", 4) == 0) { char *qm = strchr(arg[1], '?'); if (qm) *qm = 0; if (buf[0]) strcat(buf, "\r\n"); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1, "RTP-Info: url=%s;seq=%d;rtptime=%lld\r\nRange: npt=0.000-", arg[1], getTick(), (long long int) (getTickUs() / 1000000)); } if (buf[0] == 0 && sid->type == STREAM_HTTP) snprintf(buf, sizeof(buf), "Content-Type: video/mp2t"); http_response(s, 200, buf, NULL, cseq, 0); } else if (strncmp(arg[0], "TEARDOWN", 8) == 0) { buf[0] = 0; if (get_sid(s->sid)) sprintf(buf, "Session: %010d", get_session_id(s->sid)); close_stream(s->sid); http_response(s, 200, buf, NULL, cseq, 0); } else { if (strncmp(arg[0], "DESCRIBE", 8) == 0) { char sbuf[1000]; char *rv = NULL; rv = describe_streams(s, arg[1], sbuf, sizeof(sbuf)); if (!rv) { http_response(s, 404, NULL, NULL, cseq, 0); return 0; } snprintf(buf, sizeof(buf), "Content-type: application/sdp\r\nContent-Base: rtsp://%s/", get_sock_shost(s->sock)); http_response(s, 200, buf, sbuf, cseq, 0); } else if (strncmp(arg[0], "OPTIONS", 8) == 0) { http_response(s, 200, public, NULL, cseq, 0); } }