/** * We have a new address ATS should know. Addresses have to be added * with this function before they can be: updated, set in use and * destroyed. * * @param sh handle * @param address the address * @param session session handle, can be NULL * @param prop performance data for the address * @return handle to the address representation inside ATS, NULL * on error (i.e. ATS knows this exact address already) */ struct GNUNET_ATS_AddressRecord * GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_AddressRecord *ar; size_t namelen; size_t msize; uint32_t s; if (NULL == address) { /* we need a valid address */ GNUNET_break (0); return NULL; } GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); namelen = strlen (address->transport_name) + 1; msize = address->address_length + namelen; if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ) { /* address too large for us, this should not happen */ GNUNET_break (0); return NULL; } if (NOT_FOUND != find_session_id (sh, session, address)) { /* Already existing, nothing todo, but this should not happen */ GNUNET_break (0); return NULL; } s = find_empty_session_slot (sh); ar = GNUNET_new (struct GNUNET_ATS_AddressRecord); ar->sh = sh; ar->slot = s; ar->session = session; ar->address = GNUNET_HELLO_address_copy (address); GNUNET_ATS_properties_hton (&ar->properties, prop); sh->session_array[s] = ar; send_add_address_message (sh, ar); return ar; }
int read_rtsp (sockets * s) { char *arg[50]; int cseq, la, i, rlen; char *proto, *transport = NULL, *useragent = NULL; int sess_id = 0; char buf[2000]; 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(s->buf, "GET", 3) == 0)) { http_response (s , 404, NULL, NULL, 0, 0); return 0; } la = split (arg, 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(strstr(arg[1], "freq") || strstr(arg[1], "pids")) { int old_sid = s->sid; sid = (streams *) setup_stream (arg[1], s); } 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; } else if (strncasecmp ("User-Agent:", arg[i], 10) == 0) useragent = header_parameter(arg, i); 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 (useragent) strncpy(sid->useragent, useragent, 127); 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; } strcpy(ra, inet_ntoa (sid->sa.sin_addr)); buf[0] = 0; if(transport) { int s_timeout = (sid->timeout ? sid->timeout : opts.timeout_sec) / 1000; switch (sid->type) { case STREAM_RTSP_UDP: if (atoi (ra) < 239) 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_host (s->sock), ntohs (sid->sa.sin_port), ntohs (sid->sa.sin_port) + 1, // opts.start_rtp, opts.start_rtp + 1, get_sock_port(sid->rsock), get_sock_port(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, ntohs (sid->sa.sin_port), 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) { streams *sid; 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_host(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); } }
static void event_recover_connection(uint32_t sid, uint32_t cid) { int sock, ret; int yes = 1; session_t *sess; connection_t *conn; portal_t *portal; initiator_t *init; iscsi_portal_address_t *addr; struct sockaddr_in serverAddress; struct hostent *host; DEB(1, ("Event_Recover_Connection sid=%d, cid=%d\n", sid, cid)); (void) memset(&serverAddress, 0x0, sizeof(serverAddress)); LOCK_SESSIONS; sess = find_session_id(sid); if (sess == NULL) { UNLOCK_SESSIONS; return; } conn = find_connection_id(sess, cid); if (conn == NULL) { UNLOCK_SESSIONS; return; } UNLOCK_SESSIONS; conn->loginp.status = ISCSI_STATUS_CONNECTION_FAILED; /* If we can't find the portal to connect to, abort. */ if ((portal = find_portal_id(conn->portal.sid.id)) == NULL) return; init = find_initiator_id(conn->initiator_id); addr = &portal->addr; conn->portal.addr = *addr; /* translate target address */ DEB(1, ("Event_Recover_Connection Connecting to <%s>, port %d\n", addr->address, addr->port)); if ((host = gethostbyname((char *)addr->address)) == NULL) { DEB(1, ("GetHostByName failed (error %d)\n", h_errno)); return; } if (host->h_length > (int)sizeof(serverAddress.sin_addr)) { DEB(1, ("Host address length invalid (%d)\n", host->h_length)); return; } serverAddress.sin_family = host->h_addrtype; serverAddress.sin_port = htons((addr->port) ? addr->port : ISCSI_DEFAULT_PORT); serverAddress.sin_len = host->h_length; memcpy(&serverAddress.sin_addr, host->h_addr_list[0], host->h_length); /* create and connect the socket */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { DEB(1, ("Creating socket failed (error %d)\n", errno)); return; } DEB(1, ("recover_connection: Socket = %d\n", sock)); if (init) { if (!bind_socket(sock, init->address)) { DEB(1, ("Binding to interface failed (error %d)\n", errno)); close(sock); return; } } if (connect(sock, (struct sockaddr *)(void *)&serverAddress, (socklen_t)sizeof(serverAddress)) < 0) { DEB(1, ("Connecting to socket failed (error %d)\n", errno)); close(sock); return; } /* speed up socket processing */ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes, (socklen_t)sizeof(yes)); conn->loginp.socket = sock; conn->loginp.status = 0; ret = ioctl(driver, ISCSI_RESTORE_CONNECTION, &conn->loginp); if (ret) close(sock); }