int connect(int socket, const struct sockaddr *address, socklen_t address_len) { int r; nwio_tcpconf_t tcpconf; nwio_udpopt_t udpopt; r= ioctl(socket, NWIOGTCPCONF, &tcpconf); if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL)) { if (r == -1) { /* Bad file descriptor */ return -1; } return _tcp_connect(socket, address, address_len, &tcpconf); } r= ioctl(socket, NWIOGUDPOPT, &udpopt); if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL)) { if (r == -1) { /* Bad file descriptor */ return -1; } return _udp_connect(socket, address, address_len, &udpopt); } #if DEBUG fprintf(stderr, "connect: not implemented for fd %d\n", socket); #endif errno= ENOSYS; return -1; }
/* send the given packet to the peer */ ssize_t _network_send_packet(network_context_t *ctx, const void *src, size_t len) { network_context_socket_tcp_t *tcp_io_ctx; uint16_t packet_len; /* network byte order */ assert(ctx && src); assert(ctx->peer_addr_len > 0); tcp_io_ctx = (network_context_socket_tcp_t *) ctx->impl_data; assert(tcp_io_ctx); VERIFY_SOCKET(ctx); DEBUG_PEER(ctx); if (_tcp_connect(ctx) < 0) return -1; packet_len = htons(len); if (_tcp_io(GET_SOCKET(ctx), &packet_len, sizeof(packet_len), (io_func_t) write) < 0 || _tcp_io(GET_SOCKET(ctx), (void *) src, len, (io_func_t) write) < 0) return -1; /* printf("network send: %lu\n", len); */ return len; }
bool AsyncClient::connect(IPAddress ip, uint16_t port){ if (_pcb){ log_w("already connected, state %d", _pcb->state); return false; } if(!_start_async_task()){ log_e("failed to start task"); return false; } ip_addr_t addr; addr.type = IPADDR_TYPE_V4; addr.u_addr.ip4.addr = ip; tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4); if (!pcb){ log_e("pcb == NULL"); return false; } tcp_arg(pcb, this); tcp_err(pcb, &_tcp_error); if(_in_lwip_thread){ tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); } else { _tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); } return true; }
TR50_EXPORT int tr50_file_download(void* tr50, const char *thing_key, const char *src, const char *dest, char **error_msg, int is_global) { JSON *optional_params; void * json_reply_optional = NULL; const char *file_id; FILE *fp = NULL; //file vars void* socket = NULL; char tmphost[128]; char stream[READ_SIZE]; int ret = 0; int is_chunked = 0; long long filesize = 0; if ((optional_params = tr50_json_create_object()) == NULL) { return ERR_TR50_MALLOC; } tr50_json_add_string_to_object(optional_params, "fileName", src); tr50_json_add_bool_to_object(optional_params, "global", is_global); if ((!is_global) && thing_key) { tr50_json_add_string_to_object(optional_params, "thingKey", thing_key); } if ((ret = tr50_file_get_ex(tr50, src, optional_params, &json_reply_optional, error_msg)) != 0) { goto _end_err_get; } if ((json_reply_optional == NULL || ((file_id = tr50_json_get_object_item_as_string(json_reply_optional, "fileId")) == NULL))) { ret = ERR_TR50_PARMS; if (json_reply_optional) _memory_free(json_reply_optional); return ret; } if ((fp = fopen(dest, "wb")) == NULL) { return ERR_TR50_LOCAL_FILE_NOTFOUND; } snprintf(stream, 1024, GET_COMMAND, file_id, tr50_config_get_host(tr50)); snprintf(tmphost, 128, "%s", tr50_config_get_host(tr50)); if ((ret = _tcp_connect(&socket, tmphost, 80, 0)) != 0) goto _end_err_get; if ((ret = _tcp_send(socket, stream, strlen(stream), 5000)) != 0) goto _end_err_get; ret = tr50_helper_http_header_msg_decoder(socket, &is_chunked, &filesize); if (is_chunked) { do { ret = tr50_helper_chunked_reader(socket, fp); } while (ret == 0); } else { ret = tr50_helper_reader(socket, fp, filesize); } _end_err_get: if (fp) fclose(fp); if ((ret == -1) || (ret == 0)) { ret = 0; } else { ret = ERR_TR50_FILE_PUT_HTTP; } if(socket) _tcp_disconnect(socket); if (json_reply_optional) _memory_free(json_reply_optional); return ret; }
int _set_socket_timeout(int sfd) { struct timeval timeout = { .tv_sec = 0, .tv_usec = TTY_TIMEOUT_MS * 1000, }; if (setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) == -1) { perror("setsockopt failed\n"); return 1; } if (setsockopt(sfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) == -1) { perror("setsockopt failed\n"); return 1; } return 0; } int _open_tcp_connection(char *name, char *port_arg) { char *host; char *port; int ret = _parse_tcp_arg(name, port_arg, &host, &port); if (ret) { fprintf(stderr, "Error while parsing tcp arguments\n"); return -1; } int sfd = _tcp_connect(host, port); if (_set_socket_timeout(sfd)) { fprintf(stderr, "Error while setting socket options\n"); return -1; } return sfd; }
TR50_EXPORT int tr50_helper_file_upload(void* tr50, const char *thing_key, const char *src, const char *dest, const char *tags, char* is_public, char **error_msg, int is_global, int log_completion) { int ret; void * json_reply_optional = NULL; JSON *optional_params = NULL; const char *file_id; FILE *fi; //connect vars void* socket = NULL; char tmphost[128]; char stream[READ_SIZE]; char chunk_header[24]; int bytes_read = 0; if ((fi = fopen(src, "rb")) == NULL) { return ERR_TR50_LOCAL_FILE_NOTFOUND; } if ((optional_params = tr50_json_create_object()) == NULL) { return ERR_TR50_MALLOC; } tr50_json_add_bool_to_object(optional_params, "global", is_global); tr50_json_add_bool_to_object(optional_params, "logComplete", log_completion); if ((!is_global) && thing_key) { tr50_json_add_string_to_object(optional_params, "thingKey", thing_key); } if (tags) { char *token = NULL, *reent = NULL; char *tags_clone = NULL; JSON *tags_json = tr50_json_create_array(); tags_clone = _memory_clone((char*)tags, strlen(tags)); if (tags_clone != NULL) { token = strtok_r(tags_clone, ",", &reent); } while (token) { tr50_json_add_item_to_array(tags_json, tr50_json_create_string(token)); token = strtok_r(NULL, ",", &reent); } if (tags_clone) _memory_free(tags_clone); tr50_json_add_item_to_object(optional_params, "tags", tags_json); } if (is_public != NULL) { tr50_json_add_bool_to_object(optional_params, "public", *is_public); } if ((ret = tr50_file_put_ex(tr50, dest, optional_params, &json_reply_optional, error_msg)) != 0) { goto _end_err; } if ((json_reply_optional == NULL || ((file_id = tr50_json_get_object_item_as_string(json_reply_optional, "fileId")) == NULL))) { ret = ERR_TR50_PARMS; goto _end_err; } snprintf(stream, 1024, POST_COMMAND, file_id, tr50_config_get_host(tr50)); snprintf(tmphost, 128, "%s:80", tr50_config_get_host(tr50)); if ((ret = _tcp_connect(&socket, tmphost, 80, 0)) != 0) goto _end_err; if ((ret = _tcp_send(socket, stream, strlen(stream), 5000)) != 0) goto _end_err; while ((bytes_read = fread(stream, 1, 1024, fi)) > 0) { snprintf(chunk_header, 24, "%x\r\n", bytes_read); if ((ret = _tcp_send(socket, chunk_header, strlen(chunk_header), 5000)) != 0) goto _end_err; if ((ret = _tcp_send(socket, stream, bytes_read, 5000)) != 0) { goto _end_err; } if ((ret = _tcp_send(socket, "\r\n", 2, 5000)) != 0) goto _end_err; } if ((ret = _tcp_send(socket, "0\r\n\r\n", 5, 5000)) != 0) goto _end_err; if ((ret = tr50_helper_http_header_msg_decoder(socket, NULL, NULL)) != 0) goto _end_err; _end_err: if(fi) fclose(fi); if (ret == -1) { ret = ERR_TR50_FILE_PUT_HTTP; } if(socket) _tcp_disconnect(socket); //shutdown//close if (json_reply_optional) _memory_free(json_reply_optional); return ret; }
/* read a packet from the peer */ ssize_t _network_recv_packet(network_context_t *ctx, void *dst, size_t max_len) { network_context_socket_tcp_t *tcp_io_ctx; uint16_t packet_len; socket_t io_socket; int rc; assert(ctx && dst); tcp_io_ctx = (network_context_socket_tcp_t *) ctx->impl_data; assert(tcp_io_ctx); assert(tcp_io_ctx->sock_ctx); VERIFY_SOCKET(ctx); io_socket = tcp_io_ctx->base.socket; if (tcp_io_ctx->sock_ctx->is_active && _tcp_connect(ctx) < 0) return -1; if (tcp_io_ctx->sock_ctx->listening/* || (tcp_io_ctx->sock_ctx->is_active && !tcp_io_ctx->connected)*/) { socket_t tmp_sd; ctx->peer_addr_len = sizeof(ctx->peer_addr); if ((tmp_sd = accept(GET_SOCKET(ctx), &ctx->peer_addr, &ctx->peer_addr_len)) < 0) { perror("accept (network_io_tcp)"); return tmp_sd; } DEBUG_LOG(("accepted from peer, tmp_sd=%d...\n", (int) tmp_sd)); /* keep listening socket open for futher connection requests */ /* we will not reenter this function until this SYN packet has * been dispatched to the right context, and that context's * socket updated to be 'new_socket' */ assert(tcp_io_ctx->new_socket == -1); tcp_io_ctx->new_socket = tmp_sd; io_socket = tmp_sd; } DEBUG_PEER(ctx); #ifdef DEBUG if (getpeername(io_socket, &ctx->peer_addr, &ctx->peer_addr_len) < 0) { DEBUG_LOG(("getpeername failed (errno=%d)\n", errno)); return -1; } #endif if ((rc = _tcp_io(io_socket, &packet_len, sizeof(packet_len), read)) <= 0) { DEBUG_LOG(("couldn't read packet len: %d\n", rc)); return rc; } packet_len = ntohs(packet_len); if ((rc = _tcp_io(io_socket, dst, MIN(packet_len, max_len), read)) <= 0) { DEBUG_LOG(("couldn't read packet: %d\n", rc)); return rc; } if (packet_len > max_len) { /* discard unread remainder of packet */ char *dummy = (char *) alloca(packet_len - max_len); (void) _tcp_io(io_socket, dummy, packet_len - max_len, read); } /* printf("network_recv_packet: %d\n", packet_len); */ return packet_len; }