static void sdp_resp(int status, struct rr_resp *rr, struct json_object *jobj, void *arg) { struct flow *flow = arg; struct call *call = rr->call; debug("flowmgr: sdp_resp: status=%d call=%p\n", status, call); if (!call) { warning("flowmgr: sdp_resp: no call\n"); return; } if (!call_has_flow(call, flow)) { warning("flowmgr: sdp_resp: no flow: %p\n", flow); return; } if (status < 200 || status >= 300) { warning("flowmgr: sdp_resp: sdp request failed status=%d\n", status); flow_error(flow, EPROTO); } }
void flow_ice_resp(int status, struct rr_resp *rr, struct json_object *jobj, void *arg) { struct call *call = rr->call; struct flow *flow = arg; if (!call) { warning("flowmgr: ice_resp: no call\n"); return; } if (!call_has_flow(call, flow)) { warning("flowmgr: ice_resp: no flow\n"); return; } if (status < 200 || status >= 300) { warning("flowmgr: ice_resp: ice request failed status=%d\n", status); if (flow_has_ice(flow)) info("ice_resp failed but ice already working :)\n"); else flow_error(flow, EPROTO); } }
void flow_local_sdp_req(struct flow *flow, const char *type, const char *sdp) { struct call *call = flow_call(flow); struct json_object *jobj = NULL; struct rr_resp *rr; char url[256]; int err; if (!call) { warning("flowmgr: local_sdp_req: no call\n"); return; } err = rr_alloc(&rr, call_flowmgr(call), call, sdp_resp, flow); if (err) { warning("flowmgr: local_sdp_req: rest response (%m)\n", err); goto out; } snprintf(url, sizeof(url), CREQ_LSDP, call_convid(call), flow_flowid(flow)); jobj = json_object_new_object(); json_object_object_add(jobj, "type", json_object_new_string(type)); json_object_object_add(jobj, "sdp", json_object_new_string(sdp)); err = flowmgr_send_request(call_flowmgr(call), call, rr, url, HTTP_PUT, CTYPE_JSON, jobj); if (err) { warning("flowmgr: local_sdp_req: send_request() (%m)\n", err); goto out; } out: mem_deref(jobj); /* if an error happened here, we must inform the application */ if (err) { flow_error(flow, err); } }
static int prepare_rfds(struct timespec *now, struct _flow *flow, fd_set *rfds) { int rc = 0; if (!flow_in_delay(now, flow, READ) && !flow_sending(now, flow, READ)) { if (!flow->finished[READ] && flow->settings.shutdown) { warnx("server flow %u missed to shutdown", flow->id); rc = shutdown(flow->fd, SHUT_RD); if (rc == -1) warn("shutdown SHUT_RD failed"); flow->finished[READ] = 1; } } if (flow->source_settings.late_connect && !flow->connect_called ) { DEBUG_MSG(LOG_ERR, "late connecting test socket for flow %d " "after %.3fs delay", flow->id, flow->settings.delay[WRITE]); rc = connect(flow->fd, flow->addr, flow->addr_len); if (rc == -1 && errno != EINPROGRESS) { flow_error(flow, "Connect failed: %s", strerror(errno)); return -1; } flow->connect_called = 1; flow->pmtu = get_pmtu(flow->fd); } /* Altough the server flow might be finished we keep the socket in * rfd in order to check for buggy servers */ if (flow->connect_called && !flow->finished[READ]) { DEBUG_MSG(LOG_DEBUG, "adding sock of flow %d to rfds", flow->id); FD_SET(flow->fd, rfds); } return 0; }
static int name2socket(struct _flow *flow, char *server_name, unsigned port, struct sockaddr **saptr, socklen_t *lenp, char do_connect, const int read_buffer_size_req, int *read_buffer_size, const int send_buffer_size_req, int *send_buffer_size) { int fd, n; struct addrinfo hints, *res, *ressave; struct sockaddr_in *tempv4; struct sockaddr_in6 *tempv6; char service[7]; bzero(&hints, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(service, sizeof(service), "%u", port); if ((n = getaddrinfo(server_name, service, &hints, &res)) != 0) { flow_error(flow, "getaddrinfo() failed: %s", gai_strerror(n)); return -1; } ressave = res; do { int rc; fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) continue; if (send_buffer_size) *send_buffer_size = set_window_size_directed(fd, send_buffer_size_req, SO_SNDBUF); if (read_buffer_size) *read_buffer_size = set_window_size_directed(fd, read_buffer_size_req, SO_RCVBUF); if (!do_connect) break; rc = connect(fd, res->ai_addr, res->ai_addrlen); if (rc == 0) { if (res->ai_family == PF_INET) { tempv4 = (struct sockaddr_in *) res->ai_addr; strncpy(server_name, inet_ntoa(tempv4->sin_addr), 256); server_name[255] = 0; } else if (res->ai_family == PF_INET6) { tempv6 = (struct sockaddr_in6 *) res->ai_addr; inet_ntop(AF_INET6, &tempv6->sin6_addr, server_name, 256); } break; } warn("failed to connect to '%s:%d' ", server_name, port); close(fd); } while ((res = res->ai_next) != NULL); if (res == NULL) { flow_error(flow, "Could not establish connection to " "\"%s:%d\": %s", server_name, port, strerror(errno)); freeaddrinfo(ressave); return -1; } if (saptr && lenp) { *saptr = malloc(res->ai_addrlen); if (*saptr == NULL) crit("malloc(): failed"); memcpy(*saptr, res->ai_addr, res->ai_addrlen); *lenp = res->ai_addrlen; } freeaddrinfo(ressave); return fd; }
STATIC void flow_write_step(FLOW_PARAM unsigned int *hi, unsigned int *lo) { #define RI() do { \ *hi=0; \ *lo=F_w_times[W_IDLE]; \ return; \ } while(0) #define R(_x) do { \ if(_x) { \ *hi=F_w_times[W_MARK|W_ONE]; \ *lo=F_w_times[W_SPACE|W_ONE]; \ } else { \ *hi=F_w_times[W_MARK|W_ZERO]; \ *lo=F_w_times[W_SPACE|W_ZERO]; \ } \ return; \ } while(0) if(F_writer_state == FW_idle) { //DBG("W idle"); RI(); } else if(F_writer_state == FW_sync) { F_writer_bit ++; if (F_writer_bit > F_w_sync) { F_writer_state = FW_data; F_writer_bit = 0; //DBG("W last_syn"); R(1); } else { //DBG("W syn"); R(0); } } else if(F_writer_byte >= F_writer_len) { F_writer_state = FW_idle; //DBG("W end_bit"); R(0); } else if(F_writer_bit >= F_bits) { //DBG("W parity"); F_writer_bit ++; unsigned char bit; switch(F_parity) { default: case P_NONE: flow_error("Oops Parity"); *hi=0; *lo=0; return; case P_MARK: bit=1; break; case P_SPACE: bit=0; break; case P_ODD: bit=F_writer_parity^1; break; case P_EVEN: bit=F_writer_parity; break; } F_writer_byte++; F_writer_bit=0; F_writer_parity=0; R(bit & 1); } else { //DBGS("W bit %u/%u",F_writer_byte,F_writer_bit); unsigned char bit; if(F_msb) bit = F_writer_data[F_writer_byte] >> (F_bits-1-F_writer_bit); else bit = F_writer_data[F_writer_byte] >> F_writer_bit; F_writer_bit ++; F_writer_parity ^= bit; if(F_writer_bit == F_bits && F_writer_parity == P_NONE) { F_writer_byte++; F_writer_bit=0; F_writer_parity=0; } R(bit & 1); }