/*-------------------------------------------------------------------------*\ * Tries to bind socket to (address, port) \*-------------------------------------------------------------------------*/ const char *inet_trybind(p_socket ps, const char *address, const char *serv, struct addrinfo *bindhints) { struct addrinfo *iterator = NULL, *resolved = NULL; const char *err = NULL; t_socket sock = *ps; /* try resolving */ err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved)); if (err) { if (resolved) freeaddrinfo(resolved); return err; } /* iterate over resolved addresses until one is good */ for (iterator = resolved; iterator; iterator = iterator->ai_next) { if(sock == SOCKET_INVALID) { err = socket_strerror(socket_create(&sock, iterator->ai_family, iterator->ai_socktype, iterator->ai_protocol)); if(err) continue; } /* try binding to local address */ err = socket_strerror(socket_bind(&sock, (SA *) iterator->ai_addr, (socklen_t) iterator->ai_addrlen)); /* keep trying unless bind succeeded */ if (err) { if(sock != *ps) socket_destroy(&sock); } else { /* remember what we connected to, particularly the family */ *bindhints = *iterator; break; } } /* cleanup and return error */ freeaddrinfo(resolved); *ps = sock; return err; }
/*-------------------------------------------------------------------------*\ * Tries to bind socket to (address, port) \*-------------------------------------------------------------------------*/ const char *inet_trybind(p_socket ps, int *family, const char *address, const char *serv, struct addrinfo *bindhints) { struct addrinfo *iterator = NULL, *resolved = NULL; const char *err = NULL; int current_family = *family; /* translate luasocket special values to C */ if (strcmp(address, "*") == 0) address = NULL; if (!serv) serv = "0"; /* try resolving */ err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved)); if (err) { if (resolved) freeaddrinfo(resolved); return err; } /* iterate over resolved addresses until one is good */ for (iterator = resolved; iterator; iterator = iterator->ai_next) { if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { socket_destroy(ps); err = inet_trycreate(ps, iterator->ai_family, iterator->ai_socktype, iterator->ai_protocol); if (err) continue; current_family = iterator->ai_family; } /* try binding to local address */ err = socket_strerror(socket_bind(ps, (SA *) iterator->ai_addr, (socklen_t) iterator->ai_addrlen)); /* keep trying unless bind succeeded */ if (err == NULL) { *family = current_family; /* set to non-blocking after bind */ socket_setnonblocking(ps); break; } } /* cleanup and return error */ freeaddrinfo(resolved); /* here, if err is set, we failed */ return err; }
void run_server() { zctx_t *ctx; void *socket; int i, n, nclient; char buf[256]; char data[256]; char client[256]; ctx = new_context(); socket = new_socket(ctx, ZMQ_ROUTER); // socket = new_socket(ctx, ZMQ_REP); assert_result(socket_bind(socket, host), 0); // assert_result(zmq_bind(socket, host), 0); log_printf(0, "my identity=%s\n", zsocket_identity(socket)); i = 0; for (;;) { log_printf(0, "Waiting %d\n", i); nclient = zmq_recv(socket, client, sizeof(client), 0); client[nclient] = 0; log_printf(0, "From %s [%d]\n", client, nclient); n = zmq_recv(socket, buf, sizeof(buf), 0); buf[n] = 0; if (n != 0) log_printf(0, "Missing EMPTY frame! buf=%s\n", buf); n = zmq_recv(socket, buf, sizeof(buf), 0); buf[n] = 0; log_printf(0, "Got %s\n", buf); zmq_send(socket, client, nclient, ZMQ_SNDMORE); zmq_send(socket, NULL, 0, ZMQ_SNDMORE); snprintf(data, sizeof(buf), "(%s) World %d", buf, i); zmq_send(socket, data, strlen(data)+1, 0); i++; } destroy_context(ctx); }
static int sendto(struct socket *sock, const void *buffer, size_t length, int flags, struct sockaddr *addr, socklen_t addr_len) { if(!addr) return -EINVAL; /* we require sendto, not send */ struct sockaddr zero; memset(&zero, 0, sizeof(zero)); zero.sa_family = AF_INET; if(!(sock->flags & SOCK_FLAG_BOUND)) { /* grab ourselves a port to send from */ bind(sock, &zero, addr_len); socket_bind(sock, &zero, addr_len); } unsigned char tmp[length + sizeof(struct udp_header)]; memcpy(tmp + sizeof(struct udp_header), buffer, length); struct udp_header *uh = (void *)tmp; uh->src_port = *(uint16_t *)(sock->local.sa_data); uh->length = length + sizeof(struct udp_header); uh->checksum = 0; /* TODO */ uh->dest_port = *(uint16_t *)(addr->sa_data); return net_tlayer_sendto_network(sock, &sock->local, addr, (void *)tmp, length + sizeof(struct udp_header)); }
void StartServer(){ int sockstat, listsock; listsock = socket_create(STREAM,"read_callback","close_callback"); if(listsock < 0){ debug("Couldn't create socket. errorcode: "+listsock); return; } sockstat = socket_bind(listsock,port); if(sockstat < 0){ debug("Couldn't bind socket. errorcode: "+sockstat); return; } sockstat = socket_listen(listsock,"listen_callback"); if(sockstat < 0){ debug("Couldn't listen on socket. errorcode: "+sockstat); return; } }
static bool input_remote_init_network(input_remote_t *handle, uint16_t port, unsigned user) { int fd; struct addrinfo *res = NULL; port = port + user; if (!network_init()) return false; RARCH_LOG("Bringing up remote interface on port %hu.\n", (unsigned short)port); fd = socket_init((void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM); if (fd < 0) goto error; handle->net_fd[user] = fd; if (!socket_nonblock(handle->net_fd[user])) goto error; if (!socket_bind(handle->net_fd[user], res)) { RARCH_ERR("Failed to bind socket.\n"); goto error; } freeaddrinfo_retro(res); return true; error: if (res) freeaddrinfo_retro(res); return false; }
socket_p _web_server_bind(struct web_server_t* ws, uint16_t port, sockaddr_type socket_type) { socket_p socket = NULL; if (ws->socket_types & socket_type) { socket = socket_create("Web server", false); struct sockaddr* end_point = sockaddr_create(NULL, port, socket_type, 0); bool ret = socket_bind(socket, end_point); sockaddr_destroy(end_point); if (!ret) { socket_destroy(socket); socket = NULL; } } return socket; }
void http_request_startServer(pupils_t pupils){ lib_init(); socket_t * serverSocket = socket_new(); socket_bind(serverSocket, 5000); socket_listen(serverSocket); while(1){ puts("Waiting for connections"); socket_t * clientSocket = socket_accept(serverSocket); puts("New client"); char buff[BUFFER_LENGTH]; int readLength = socket_read(clientSocket, buff, BUFFER_LENGTH); if(readLength == 0){ socket_close(clientSocket); socket_free(clientSocket); puts("Skipping empty request"); continue; } printf("Got Request:\n---------------\n%s\n----------------\n", buff); http_request_t req = http_request_parse(buff); printf("Method: %s\nURI: %s\n", req.method, req.uri); puts("Data:"); for(int i = 0; i < req.formLength; i++){ char * kvStr = keyvalue_toString(&req.form[i]); printf("\t%s\n", kvStr); free(kvStr); } http_request_chooseMethod(req, clientSocket, pupils); socket_close(clientSocket); socket_free(clientSocket); } socket_close(serverSocket); socket_free(serverSocket); lib_free(); }
void f_socket_bind (void) { int i, fd, port, num_arg = st_num_arg; svalue_t *arg; char addr[ADDR_BUF_SIZE]; arg = sp - num_arg + 1; if ((num_arg == 3) && (arg[2].type != T_STRING)) { bad_arg(3, F_SOCKET_BIND); } fd = arg[0].u.number; get_socket_address(fd, addr, &port, 0); if (VALID_SOCKET("bind")) { i = socket_bind(fd, arg[1].u.number, (num_arg == 3 ? arg[2].u.string : 0)); pop_n_elems(num_arg - 1); sp->u.number = i; } else { pop_n_elems(num_arg - 1); sp->u.number = EESECURITY; } }
ssize_t socket_send(net_socket *socket, const void *data, size_t length, int flags) { if (socket->peer.ss_len == 0) return EDESTADDRREQ; if (socket->address.ss_len == 0) { // try to bind first status_t status = socket_bind(socket, NULL, 0); if (status < B_OK) return status; } // TODO: useful, maybe even computed header space! net_buffer *buffer = gNetBufferModule.create(256); if (buffer == NULL) return ENOBUFS; // copy data into buffer if (gNetBufferModule.append(buffer, data, length) < B_OK) { gNetBufferModule.free(buffer); return ENOBUFS; } buffer->flags = flags; memcpy(buffer->source, &socket->address, socket->address.ss_len); memcpy(buffer->destination, &socket->peer, socket->peer.ss_len); status_t status = socket->first_info->send_data(socket->first_protocol, buffer); if (status < B_OK) { gNetBufferModule.free(buffer); return status; } return length; }
static void tcp_sock_bind(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) { int rc; struct sockaddr *addr; size_t addr_len; socket_core_t *sock_core; tcp_sockdata_t *socket; log_msg(LVL_DEBUG, "tcp_sock_bind()"); log_msg(LVL_DEBUG, " - async_data_write_accept"); rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len); if (rc != EOK) { async_answer_0(callid, rc); return; } log_msg(LVL_DEBUG, " - call socket_bind"); rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), addr, addr_len, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, last_used_port); if (rc != EOK) { async_answer_0(callid, rc); return; } log_msg(LVL_DEBUG, " - call socket_cores_find"); sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call)); if (sock_core != NULL) { socket = (tcp_sockdata_t *)sock_core->specific_data; /* XXX Anything to do? */ (void) socket; } log_msg(LVL_DEBUG, " - success"); async_answer_0(callid, EOK); }
int main() { lib_init(); socket_t * server = socket_new(); socket_bind(server, 5000); socket_listen(server); char buf[10000]; char pathBuf[256]; socket_t * client = NULL; while(1) { client = socket_accept(server); socket_read(client, buf, sizeof(buf)); http_request_t rs; rs = http_request_parse(buf); server_reply(client,rs); } socket_free(server); socket_free(client); lib_free(); return 0; }
/** Initialize Netplay discovery (client) */ bool init_netplay_discovery(void) { struct addrinfo *addr = NULL; int fd = socket_init((void **) &addr, 0, NULL, SOCKET_TYPE_DATAGRAM); if (fd < 0) goto error; if (!socket_bind(fd, (void*)addr)) { socket_close(fd); goto error; } lan_ad_client_fd = fd; freeaddrinfo_retro(addr); return true; error: if (addr) freeaddrinfo_retro(addr); RARCH_ERR("Failed to initialize netplay advertisement client socket.\n"); return false; }
int main() { db_t* base = db_new("workers.db"); lib_init(); socket_t* server = socket_new(); socket_bind(server, PORT); socket_listen(server); char buffer[10000]; while(true) { puts("Waiting for client...!"); socket_t* client = socket_accept(server); if(socket_read(client, buffer, sizeof(buffer)) <= 0) { socket_close(client); socket_free(client); continue; } printf("Request:\n%s\n", buffer); http_request_t request = http_request_parse(buffer); server_answerRequest(request, client, base); socket_free(client); } socket_free(server); lib_free(); db_free(base); return 0; }
int main() { lib_init(); socket_t * server = socket_new(); socket_bind(server, 5000); socket_listen(server); char buf[10000]; char pathBuf[256]; socket_t * client = NULL; while(1) { client = socket_accept(server); socket_read(client, buf, sizeof(buf)); if (strlen(buf) == 0) continue; printf(">> Got request:\n%s\n", buf); http_getPath(buf, pathBuf, sizeof(pathBuf)); http_request_t request = http_request_parse(buf); if (strcmp(request.uri, "/") == 0) { server_homepage(client); } else if (strcmp(request.uri, "/api/admins") == 0) { server_database(client); } else if (strcmp(request.uri, "/api/admins/") > 0) { server_database_id(client, &request); } else { error_massage(client, "404 - NOT FOUND!"); } socket_free(client); } socket_free(server); lib_free(); return 0; }
DECLARE_TEST(udp, datagram_ipv6) { network_address_t** address_local = 0; network_address_t* address = 0; network_address_t* address_server = 0; test_datagram_arg_t client_arg[4]; int server_port; int state, iaddr, asize; thread_t threads[5]; socket_t* sock_server; socket_t* sock_client[4]; if (!network_supports_ipv6()) return 0; sock_server = udp_socket_allocate(); sock_client[0] = udp_socket_allocate(); sock_client[1] = udp_socket_allocate(); sock_client[2] = udp_socket_allocate(); sock_client[3] = udp_socket_allocate(); address_local = network_address_local(); for (iaddr = 0, asize = array_size(address_local); iaddr < asize; ++iaddr) { if (network_address_family(address_local[iaddr]) == NETWORK_ADDRESSFAMILY_IPV6) { address = address_local[iaddr]; break; } } EXPECT_NE(address, 0); do { server_port = random32_range(1024, 35535); network_address_ip_set_port(address, server_port); if (socket_bind(sock_server, address)) break; } while (true); address_server = network_address_clone(address); network_address_ip_set_port(address_server, server_port); network_address_array_deallocate(address_local); state = socket_state(sock_server); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[0]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[1]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[2]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[3]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); socket_set_blocking(sock_server, true); socket_set_blocking(sock_client[0], true); socket_set_blocking(sock_client[1], true); socket_set_blocking(sock_client[2], true); socket_set_blocking(sock_client[3], true); client_arg[0].sock = sock_client[0]; client_arg[0].target = address_server; client_arg[1].sock = sock_client[1]; client_arg[1].target = address_server; client_arg[2].sock = sock_client[2]; client_arg[2].target = address_server; client_arg[3].sock = sock_client[3]; client_arg[3].target = address_server; thread_initialize(&threads[0], datagram_server_blocking_thread, sock_server, STRING_CONST("server_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[1], datagram_client_blocking_thread, &client_arg[0], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[2], datagram_client_blocking_thread, &client_arg[1], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[3], datagram_client_blocking_thread, &client_arg[2], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[4], datagram_client_blocking_thread, &client_arg[3], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&threads[0]); thread_start(&threads[1]); thread_start(&threads[2]); thread_start(&threads[3]); thread_start(&threads[4]); test_wait_for_threads_startup(threads, 5); thread_finalize(&threads[0]); thread_finalize(&threads[1]); thread_finalize(&threads[2]); thread_finalize(&threads[3]); thread_finalize(&threads[4]); socket_deallocate(sock_server); socket_deallocate(sock_client[0]); socket_deallocate(sock_client[1]); socket_deallocate(sock_client[2]); socket_deallocate(sock_client[3]); memory_deallocate(address_server); return 0; }
DECLARE_TEST(udp, stream_ipv6) { network_address_t** address_local = 0; network_address_t* address = 0; int server_port, client_port; int state, iaddr, asize; thread_t threads[2]; socket_t* sock_server; socket_t* sock_client; if (!network_supports_ipv6()) return 0; sock_server = udp_socket_allocate(); sock_client = udp_socket_allocate(); address_local = network_address_local(); for (iaddr = 0, asize = array_size(address_local); iaddr < asize; ++iaddr) { if (network_address_family(address_local[iaddr]) == NETWORK_ADDRESSFAMILY_IPV6) { address = address_local[iaddr]; break; } } EXPECT_NE(address, 0); do { server_port = random32_range(1024, 35535); network_address_ip_set_port(address, server_port); if (socket_bind(sock_server, address)) break; } while (true); do { client_port = random32_range(1024, 35535); network_address_ip_set_port(address, client_port); if (socket_bind(sock_client, address)) break; } while (true); socket_set_blocking(sock_server, false); socket_set_blocking(sock_client, false); network_address_ip_set_port(address, client_port); socket_connect(sock_server, address, 0); network_address_ip_set_port(address, server_port); socket_connect(sock_client, address, 0); network_address_array_deallocate(address_local); state = socket_state(sock_server); EXPECT_TRUE(state == SOCKETSTATE_CONNECTED); state = socket_state(sock_client); EXPECT_TRUE(state == SOCKETSTATE_CONNECTED); socket_set_blocking(sock_server, true); socket_set_blocking(sock_client, true); thread_initialize(&threads[0], stream_blocking_thread, sock_server, STRING_CONST("io_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[1], stream_blocking_thread, sock_client, STRING_CONST("io_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&threads[0]); thread_start(&threads[1]); test_wait_for_threads_startup(threads, 2); thread_finalize(&threads[0]); thread_finalize(&threads[1]); socket_deallocate(sock_server); socket_deallocate(sock_client); return 0; }
int main(int argc, char **argv){ char addr[32]; if (argc < 4){ fprintf(stdout,"not enough args\n"); fprintf(stdout,"usage: prog <auscoutd address> <port> <port>\n"); fprintf(stdout,"address - mock auscoud server address, e.g. \"localhost\"\n"); fprintf(stdout,"port - mock auscoutd server port e.g. 4005\n"); fprintf(stdout,"port - port to recieve init from auscout driver, e.g. 4009\n"); return 0; } /* progname <auscoutd address> <auscoutd port> <driver port>*/ const char *auscoutd_address = argv[1]; const int port = atoi(argv[2]); const int driver_port = atoi(argv[3]); int subscr_port = port + 2; int result_port = port + 3; int table_port = port + 1; snprintf(addr, 32, "tcp://%s:%d", auscoutd_address, table_port); fprintf(stdout,"register as table with %s\n", addr); void *ctx = zmq_init(1); assert(ctx); assert(register_table(ctx, addr) == 0); /* skt to recieve number of files to be sent from auscout driver program */ snprintf(addr, 32, "tcp://*:%d", driver_port); void *prepskt = socket_bind(ctx, ZMQ_PAIR, addr); assert(prepskt); snprintf(addr, 32, "tcp://%s:%d", auscoutd_address, subscr_port); void *subscr_skt = socket_connect(ctx, ZMQ_SUB, addr); assert(subscr_skt); assert(zmq_setsockopt(subscr_skt, ZMQ_SUBSCRIBE, "phash.", 6) == 0); snprintf(addr, 32, "tcp://%s:%d", auscoutd_address, result_port); void *result_skt = socket_connect(ctx, ZMQ_REQ, addr); assert(result_skt); struct timespec seed_ts; clock_gettime(CLOCK_REALTIME, &seed_ts); srand(seed_ts.tv_nsec); uint8_t cmd, thrdnum, tblnum; struct timespec start_ts, end_ts, diff_ts; uint32_t uid, nbframes, count = 0, nbquerys; void *data; int64_t more; size_t msg_size, more_size = sizeof(int64_t); float cs = 0.05555f; fprintf(stdout,"\nready to recieve subscription messages from auscoutd ...\n\n"); while (1){ recieve_msg(prepskt, &msg_size, &more, &more_size, &data); assert(msg_size == sizeof(uint32_t)); memcpy(&nbquerys, data, sizeof(uint32_t)); free(data); fprintf(stdout,"expecting %d querys\n\n", nbquerys); clock_gettime(CLOCK_MONOTONIC, &start_ts); count = 0; do { /* recieve topic */ recieve_msg(subscr_skt, &msg_size, &more, &more_size, &data); free(data); /* recieve cmd */ recieve_msg(subscr_skt, &msg_size, &more, &more_size, &data); memcpy(&cmd, data, sizeof(uint8_t)); free(data); recieve_msg(subscr_skt, &msg_size, &more, &more_size, &data); memcpy(&nbframes, data, sizeof(uint32_t)); nbframes = nettohost32(nbframes); free(data); /* recieve hash */ recieve_msg(subscr_skt, &msg_size, &more, &more_size, &data); free(data); recieve_msg(subscr_skt, &msg_size, &more, &more_size, &data); memcpy(&thrdnum, data, sizeof(uint8_t)); free(data); recieve_msg(subscr_skt, &msg_size, &more, &more_size, &data); memcpy(&uid, data, sizeof(uint32_t)); uid = nettohost32(uid); free(data); if (cmd == 1){ /* recieved lookup */ uid = 0; /* send back random integer id*/ cs = 0.5555; fprintf(stdout,"(%d) lookup: %u frames\n",count,nbframes); fprintf(stdout," reply : thrdnum %u | uid %u | cs %f\n\n",thrdnum,uid,cs); uid = hosttonet32(uid); cs = hosttonetf(cs); sendmore_msg_vsm(result_skt, &thrdnum, sizeof(uint8_t)); sendmore_msg_vsm(result_skt, &uid, sizeof(uint32_t)); send_msg_vsm(result_skt, &cs, sizeof(float)); recieve_msg(result_skt, &msg_size, &more, &more_size, &data); free(data); } else if (cmd == 2){ tblnum = thrdnum; /* recieved submission */ fprintf(stdout,"(%d) submit: %u frames | %u table\n",count,nbframes,tblnum); fprintf(stdout," no reply\n\n"); } fprintf(stdout,"**************************************\n"); } while (++count < nbquerys); clock_gettime(CLOCK_MONOTONIC, &end_ts); diff_ts = diff_timespec(start_ts, end_ts); unsigned long long total_ull = 1000000000*diff_ts.tv_sec + diff_ts.tv_nsec; float total_secs = (float)total_ull/1000000000.0f; float rate = (float)nbquerys/total_secs; fprintf(stdout,"recieved %d querys in %f secs - %f querys/sec\n",\ nbquerys, total_secs, rate); } zmq_close(subscr_skt); zmq_close(result_skt); zmq_close(prepskt); zmq_term(ctx); return 0; }
int main() { lib_init(); printf("PORT: %i\n\n", PORT); socket_t * server = socket_new(); socket_bind(server, PORT); socket_listen(server); char buffer[10000]; socket_t * client = NULL; // работа с базой данных const char * dbFile = "ScrumMaster.db"; db_t * db = db_new(dbFile); // работа с базой данных while(1) { client = socket_accept(server); socket_read(client, buffer, sizeof(buffer)); if(strlen(buffer) != 0) { printf(">> Got request:\n%s\n", buffer); http_request_t request = http_request_parse(buffer); if (strcmp(request.uri, "/") == 0) { server_homepage(client); } else if (strcmp(request.uri, "/api/ScrumMasters") == 0) // else if (strncmp(request.uri, "/api/ScrumMasters?", 18) == 0) { server_masters(client, &request, db); } else if (strncmp(request.uri, "/api/ScrumMasters/", 18) == 0) { server_mastersByID(client, &request, db); } else if (strcmp(request.uri, "/ScrumMasters") == 0) { server_mastersHtml(client, &request, db); } else if (strncmp(request.uri, "/ScrumMasters/", 14) == 0) { server_mastersHtmlByID(client, &request, db); } else if (strcmp(request.uri, "/new-ScrumMaster") == 0) { server_mastersHtmlPOST(client, &request, db); } else { server_notFound(client); } } } db_free(db); socket_free(client); socket_free(server); lib_free(); return 0; }
void create() { int tmp; s=socket_create(DATAGRAM_BINARY, "ReceiveData"); tmp=socket_bind(s, LISTEN_PORT); }
int main(void) { WSADATA Data; SOCKADDR_IN recvSockAddr; SOCKET recvSocket; int status; int numrcv = 0; struct hostent * remoteHost; char * ip; const char * host_name = "pb-homework.appspot.com"; char buffer[MAXBUFLEN]; memset(buffer,0,MAXBUFLEN); // Initialize Windows Socket DLL status = WSAStartup(MAKEWORD(2, 2), &Data); if(status != 0) { printf("ERROR: WSAStartup unsuccessful\r\n"); return 0; } // Get IP address from host name remoteHost = gethostbyname(host_name); ip = inet_ntoa(*(struct in_addr *)*remoteHost->h_addr_list); printf("IP address is: %s.\n", ip); memset(&recvSockAddr, 0, sizeof(recvSockAddr)); // zero the sockaddr_in structure recvSockAddr.sin_port=htons(PORT); // specify the port portion of the address recvSockAddr.sin_family=AF_INET; // specify the address family as Internet recvSockAddr.sin_addr.s_addr= inet_addr(ip); // specify ip address // Create socket recvSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(recvSocket == INVALID_SOCKET) { printf("ERROR: socket unsuccessful\r\n"); WSACleanup(); system("pause"); return 0; } // Connect if(connect(recvSocket,(SOCKADDR*)&recvSockAddr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { printf("ERROR: socket could not connect\r\n"); closesocket(recvSocket); WSACleanup(); return 0; } // Send request char request[200]; sprintf(request, "GET /test/var/24?format=json HTTP/1.1\r\nHost:%s\r\n\r\n", host_name); // add Host header with host_name value send(recvSocket, request, strlen(request), 0); // Receieve numrcv = recv(recvSocket, buffer, MAXBUFLEN, NO_FLAGS_SET); if (numrcv == SOCKET_ERROR) { printf("ERROR: recvfrom unsuccessful\r\n"); status = closesocket(recvSocket); if(status == SOCKET_ERROR) printf("ERROR: closesocket unsuccessful\r\n"); status = WSACleanup(); if (status == SOCKET_ERROR) printf("ERROR: WSACleanup unsuccessful\r\n"); system("pause"); return(1); } // Print out receieved socket data printf("%s\r\n", buffer); char * json=strstr(buffer,"{"); cJSON * SI = cJSON_CreateObject(); SI=cJSON_Parse(json); author_t * author=malloc(sizeof(author_t)); author->author=malloc(strlen(cJSON_GetObjectItem(SI,"author")->valuestring)+1); strcpy(author->author,cJSON_GetObjectItem(SI,"author")->valuestring); author->quote=malloc(strlen(cJSON_GetObjectItem(SI,"quote")->valuestring)+1); strcpy(author->quote,cJSON_GetObjectItem(SI,"quote")->valuestring); time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); author->time=malloc(strlen(asctime(timeinfo))); strcpy(author->time,asctime(timeinfo)); author->time[strlen(author->time)-1]='\0'; cJSON * SM = cJSON_CreateObject(); cJSON_AddItemToObject(SM, "author", cJSON_CreateString(author->author)); cJSON_AddItemToObject(SM, "quote", cJSON_CreateString(author->quote)); cJSON_AddItemToObject(SM, "time", cJSON_CreateString(author->time)); char * jsonSM = cJSON_Print(SM); system("pause"); lib_init(); socket_t * server = socket_new(); socket_bind(server, 5000); socket_listen(server); char buf[10000]; socket_t * client = NULL; while(1) { client = socket_accept(server); socket_read(client, buf, sizeof(buf)); printf("%s",buf); if (strlen(buf) != 0){ http_request_t rs; rs = http_request_parse(buf); if (strcmp(rs.method,"GET") == 0 && strcmp(rs.uri, "/info") == 0 ) { server_info(client); } if (strcmp(rs.method,"GET") == 0 && strcmp(rs.uri, "/external") == 0 ) { server_sent(client,jsonSM); } } } system("pause"); return 0; }
int main(){ lib_init(); socket_t * server = socket_new(); socket_bind(server, 5000); socket_listen(server); char buffer[10000]; socket_t * client = NULL; list_t * pupils = list_new(); char jsonText[10000]; FILE * fp = fopen("pupil.json","r"); fread(jsonText,sizeof(char),10000,fp); pupil_createPupilsList(pupils,cJSON_Parse(jsonText)); while (1) { socket_t * client = socket_accept(server); socket_read(client, buffer, sizeof(buffer)); printf("%s", buffer); server_request_t request = server_request_parse(buffer); if (strcmp(request.method, "GET") == 0){ if(strcmp(request.uri,"/")==0){ server_openPage(client); } else if (strcmp(request.uri,"/api/pupils")==0){ server_sendJson(client,pupil_listToJson(pupils)); } else if(strncmp(request.uri,"/api/pupils/",strlen("/api/pupils/"))==0){ int id; int num = sscanf(request.uri, "/api/pupils/%d", &id); if(num != 0){ pupil_t * p = server_getPupilById(pupils,id); if(p == NULL){ server_sendWrongIndex(client); } else server_sendJson(client,pupil_pupilToJson(p)); } } else if(strcmp(request.uri, "/pupils")==0){ server_sendListAsHtml(client,pupils); } else if(strncmp(request.uri,"/pupils/",strlen("/pupils/"))==0){ int id; int num = sscanf(request.uri, "/pupils/%d", &id); if(num != 0){ pupil_t * p = server_getPupilById(pupils,id); if(p == NULL){ server_wrongIndex_html(client); } else server_sendHtml(client,pupil_getHtml(p,pupil_getId(p))); } } else if(strcmp(request.uri, "/new-pupil")==0){ server_addPupilHtml(client,pupils); } } else if (strcmp(request.method, "DELETE") == 0){ if (strstr(request.uri, "/api/pupils/") != NULL){ int id; int isNumber = sscanf(request.uri, "/api/pupils/%d", &id); if (isNumber){ server_deletePupil(client,pupils, id); } else{ server_sendWrongIndex(client); } } else if (strstr(request.uri,"/pupils/")!= NULL){ int Id; int num = sscanf(request.uri,"/pupils/%d", &Id); if(num){ server_deletePupil_html(client,pupils,Id); } else { server_wrongIndex_html(client); } } } else if (strcmp(request.method, "POST") == 0){ if (strcmp(request.uri,"/api/pupils")==0) { server_addPupil(client,pupils,buffer); } else if (strcmp(request.uri,"/pupils")==0) { server_newHtmlPupil(client,pupils,buffer); } } socket_free(client); } socket_free(client); socket_free(server); list_free(pupils); lib_free(); return 0; }
void startServer(list_t *list) { lib_init(); socket_t * serverSocket = socket_new(); socket_bind(serverSocket, 5000); socket_listen(serverSocket); while(1) { puts("Waiting for connections"); socket_t * clientSocket = socket_accept(serverSocket); char buff[BUFFER_LENGTH]; int readLength = socket_read(clientSocket, buff, BUFFER_LENGTH); if(readLength == 0) { socket_close(clientSocket); socket_free(clientSocket); puts("Skipping empty request"); continue; } printf("Got Request:\n---------------\n%s\n----------------\n", buff); http_request_t req = http_parse(buff); printf("Method: %s\nURI: %s\n", req.method, req.uri); puts("Data:"); for(int i = 0; i < req.formLength; i++) { char * kvStr = keyvalue_toString(&req.form[i]); printf("\t%s\n", kvStr); free(kvStr); } if(!strcmp(req.uri, "/")) { char smallMSG[100]; sprintf(smallMSG, "<h1>HELLO ALL!!!</h1>"); char result_msg[MSG_LENGTH]; //resp_form(HTML, smallMSG, 200, result_msg); sprintf(result_msg, "HTTP/1.1 200 OK\n" "Content-length: %zu\n" "Content-type: application/xml\n" "\n" "%s\0", strlen(smallMSG), smallMSG); socket_write_string(clientSocket, result_msg); } else if(!strcmp(req.uri, "/info")) { char result_msg[MSG_LENGTH]; resp_form(XML, first_task_func(), 200, result_msg); socket_write_string(clientSocket, result_msg); } else if (!strcmp(req.uri, "/external")) { static const char * requestFormat = "%s %s HTTP/1.1\r\n" "Content-Type: text\r\n" "Content-Length: %zu\r\n\r\n" "%s"; socket_t* serverSock = socket_new (); socket_connect(serverSock, "216.58.209.49", 80); char uri [256]; strcpy (uri, "http://pb-homework.appspot.com/test/var/5?format=xml"); char req [1024]; sprintf (req, requestFormat, "GET", uri, NULL, NULL, NULL); socket_write(serverSock, req, strlen (req)); char responce [1024]; socket_read (serverSock, responce, 1024); int contentLength = 0; sscanf (strstr(responce, "Content-Length: ") + strlen ("Content-Length: "), "%d", &contentLength); char* data = strstr (responce, "\r\n\r\n") + 4; socket_free(serverSock); data = second_task_func(data); char result_msg[MSG_LENGTH]; resp_form(XML, data, 200, result_msg); socket_write_string(clientSocket, result_msg); } else { char result_msg[MSG_LENGTH]; resp_form(XML, NULL, 404, result_msg); socket_write_string(clientSocket, result_msg); return; } socket_close(clientSocket); socket_free(clientSocket); } socket_close(serverSocket); socket_free(serverSocket); lib_free(); }
ssize_t socket_send(net_socket* socket, msghdr* header, const void* data, size_t length, int flags) { const sockaddr* address = NULL; socklen_t addressLength = 0; size_t bytesLeft = length; if (length > SSIZE_MAX) return B_BAD_VALUE; ancillary_data_container* ancillaryData = NULL; CObjectDeleter<ancillary_data_container> ancillaryDataDeleter(NULL, &delete_ancillary_data_container); if (header != NULL) { address = (const sockaddr*)header->msg_name; addressLength = header->msg_namelen; // get the ancillary data if (header->msg_control != NULL) { ancillaryData = create_ancillary_data_container(); if (ancillaryData == NULL) return B_NO_MEMORY; ancillaryDataDeleter.SetTo(ancillaryData); status_t status = add_ancillary_data(socket, ancillaryData, (cmsghdr*)header->msg_control, header->msg_controllen); if (status != B_OK) return status; } } if (addressLength == 0) address = NULL; else if (address == NULL) return B_BAD_VALUE; if (socket->peer.ss_len != 0) { if (address != NULL) return EISCONN; // socket is connected, we use that address address = (struct sockaddr*)&socket->peer; addressLength = socket->peer.ss_len; } if (address == NULL || addressLength == 0) { // don't know where to send to: return EDESTADDRREQ; } if ((socket->first_info->flags & NET_PROTOCOL_ATOMIC_MESSAGES) != 0 && bytesLeft > socket->send.buffer_size) return EMSGSIZE; if (socket->address.ss_len == 0) { // try to bind first status_t status = socket_bind(socket, NULL, 0); if (status != B_OK) return status; } // If the protocol has a send_data_no_buffer() hook, we use that one. if (socket->first_info->send_data_no_buffer != NULL) { iovec stackVec = { (void*)data, length }; iovec* vecs = header ? header->msg_iov : &stackVec; int vecCount = header ? header->msg_iovlen : 1; ssize_t written = socket->first_info->send_data_no_buffer( socket->first_protocol, vecs, vecCount, ancillaryData, address, addressLength); if (written > 0) ancillaryDataDeleter.Detach(); return written; } // By convention, if a header is given, the (data, length) equals the first // iovec. So drop the header, if it is the only iovec. Otherwise compute // the size of the remaining ones. if (header != NULL) { if (header->msg_iovlen <= 1) header = NULL; else { // TODO: The iovecs have already been copied to kernel space. Simplify! bytesLeft += compute_user_iovec_length(header->msg_iov + 1, header->msg_iovlen - 1); } } ssize_t bytesSent = 0; size_t vecOffset = 0; uint32 vecIndex = 0; while (bytesLeft > 0) { // TODO: useful, maybe even computed header space! net_buffer* buffer = gNetBufferModule.create(256); if (buffer == NULL) return ENOBUFS; while (buffer->size < socket->send.buffer_size && buffer->size < bytesLeft) { if (vecIndex > 0 && vecOffset == 0) { // retrieve next iovec buffer from header iovec vec; if (user_memcpy(&vec, header->msg_iov + vecIndex, sizeof(iovec)) < B_OK) { gNetBufferModule.free(buffer); return B_BAD_ADDRESS; } data = vec.iov_base; length = vec.iov_len; } size_t bytes = length; if (buffer->size + bytes > socket->send.buffer_size) bytes = socket->send.buffer_size - buffer->size; if (gNetBufferModule.append(buffer, data, bytes) < B_OK) { gNetBufferModule.free(buffer); return ENOBUFS; } if (bytes != length) { // partial send vecOffset = bytes; length -= vecOffset; data = (uint8*)data + vecOffset; } else if (header != NULL) { // proceed with next buffer, if any vecOffset = 0; vecIndex++; if (vecIndex >= (uint32)header->msg_iovlen) break; } } // attach ancillary data to the first buffer status_t status = B_OK; if (ancillaryData != NULL) { gNetBufferModule.set_ancillary_data(buffer, ancillaryData); ancillaryDataDeleter.Detach(); ancillaryData = NULL; } size_t bufferSize = buffer->size; buffer->flags = flags; memcpy(buffer->source, &socket->address, socket->address.ss_len); memcpy(buffer->destination, address, addressLength); buffer->destination->sa_len = addressLength; if (status == B_OK) { status = socket->first_info->send_data(socket->first_protocol, buffer); } if (status != B_OK) { size_t sizeAfterSend = buffer->size; gNetBufferModule.free(buffer); if ((sizeAfterSend != bufferSize || bytesSent > 0) && (status == B_INTERRUPTED || status == B_WOULD_BLOCK)) { // this appears to be a partial write return bytesSent + (bufferSize - sizeAfterSend); } return status; } bytesLeft -= bufferSize; bytesSent += bufferSize; } return bytesSent; }
static int socket_dev_ioctl(dev_cookie cookie, int op, void *buf, size_t len) { socket_dev *s = (socket_dev *)cookie; _socket_api_args_t args; int err; // copy the args over from user space err = user_memcpy(&args, buf, min(sizeof(args), len)); if(err < 0) return err; if(s->id < 0) { switch(op) { case _SOCKET_API_CREATE: err = s->id = socket_create(args.u.create.type, args.u.create.flags); break; case _SOCKET_API_ASSOCIATE_SOCKET: s->id = args.u.associate.id; err = NO_ERROR; break; default: err = ERR_INVALID_ARGS; } } else { switch(op) { case _SOCKET_API_BIND: err = socket_bind(s->id, args.u.bind.saddr); break; case _SOCKET_API_CONNECT: err = socket_connect(s->id, args.u.connect.saddr); break; case _SOCKET_API_LISTEN: err = socket_listen(s->id); break; case _SOCKET_API_ACCEPT: { // this one is a little tricky, we have a new socket we need to associate with a file descriptor sock_id id; int fd; _socket_api_args_t new_args; char socket_dev_path[SYS_MAX_PATH_LEN]; id = socket_accept(s->id, args.u.accept.saddr); if(id < 0) { err = id; break; } // we have the new id, open a new file descriptor in user space strcpy(socket_dev_path, "/dev/net/socket"); fd = vfs_open(socket_dev_path, 0, false); if(fd < 0) { socket_close(id); err = fd; break; } // now do a special call on this file descriptor that associates it with this socket new_args.u.associate.id = id; err = vfs_ioctl(fd, _SOCKET_API_ASSOCIATE_SOCKET, &new_args, sizeof(new_args), false); if(err < 0) { socket_close(id); break; } err = fd; break; } case _SOCKET_API_RECVFROM: err = socket_recvfrom(s->id, args.u.transfer.buf, args.u.transfer.len, args.u.transfer.saddr); break; case _SOCKET_API_RECVFROM_ETC: err = socket_recvfrom_etc(s->id, args.u.transfer.buf, args.u.transfer.len, args.u.transfer.saddr, args.u.transfer.flags, args.u.transfer.timeout); break; case _SOCKET_API_SENDTO: err = socket_sendto(s->id, args.u.transfer.buf, args.u.transfer.len, args.u.transfer.saddr); break; default: err = ERR_INVALID_ARGS; } } return err; }
static void udp_sock_bind(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) { int rc; struct sockaddr_in *addr; size_t addr_size; socket_core_t *sock_core; udp_sockdata_t *socket; udp_sock_t fsock; udp_error_t urc; log_msg(LVL_DEBUG, "udp_sock_bind()"); log_msg(LVL_DEBUG, " - async_data_write_accept"); addr = NULL; rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size); if (rc != EOK) { async_answer_0(callid, rc); goto out; } log_msg(LVL_DEBUG, " - call socket_bind"); rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, last_used_port); if (rc != EOK) { async_answer_0(callid, rc); goto out; } if (addr_size != sizeof(struct sockaddr_in)) { async_answer_0(callid, EINVAL); goto out; } log_msg(LVL_DEBUG, " - call socket_cores_find"); sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call)); if (sock_core == NULL) { async_answer_0(callid, ENOENT); goto out; } socket = (udp_sockdata_t *)sock_core->specific_data; fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); fsock.port = sock_core->port; urc = udp_uc_set_local(socket->assoc, &fsock); switch (urc) { case UDP_EOK: rc = EOK; break; /* case TCP_ENOTEXIST: rc = ENOTCONN; break; case TCP_ECLOSING: rc = ENOTCONN; break; case TCP_ERESET: rc = ECONNABORTED; break;*/ default: assert(false); } log_msg(LVL_DEBUG, " - success"); async_answer_0(callid, rc); out: if (addr != NULL) free(addr); }
/* ** err = socket.bind(fd, addr, port) */ static int lsocket_bind(lua_State *L) { int err = socket_bind(luaL_checkint(L, 1), luaL_checkstring(L, 2), luaL_optint(L, 3, 0)); lua_pushinteger(L, err); return 1; }
static void udp_sock_sendto(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) { int socket_id; int fragments; int index; struct sockaddr_in *addr; size_t addr_size; socket_core_t *sock_core; udp_sockdata_t *socket; udp_sock_t fsock, *fsockp; ipc_call_t answer; ipc_callid_t wcallid; size_t length; uint8_t buffer[UDP_FRAGMENT_SIZE]; udp_error_t urc; int rc; log_msg(LVL_DEBUG, "udp_sock_send()"); addr = NULL; if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) { rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size); if (rc != EOK) { async_answer_0(callid, rc); goto out; } if (addr_size != sizeof(struct sockaddr_in)) { async_answer_0(callid, EINVAL); goto out; } fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); fsock.port = uint16_t_be2host(addr->sin_port); fsockp = &fsock; } else { fsockp = NULL; } socket_id = SOCKET_GET_SOCKET_ID(call); fragments = SOCKET_GET_DATA_FRAGMENTS(call); SOCKET_GET_FLAGS(call); sock_core = socket_cores_find(&client->sockets, socket_id); if (sock_core == NULL) { async_answer_0(callid, ENOTSOCK); goto out; } if (sock_core->port == 0) { /* Implicitly bind socket to port */ rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, last_used_port); if (rc != EOK) { async_answer_0(callid, rc); goto out; } } socket = (udp_sockdata_t *)sock_core->specific_data; fibril_mutex_lock(&socket->lock); if (socket->assoc->ident.local.addr.ipv4 == UDP_IPV4_ANY) { /* Determine local IP address */ inet_addr_t loc_addr, rem_addr; rem_addr.ipv4 = fsockp ? fsock.addr.ipv4 : socket->assoc->ident.foreign.addr.ipv4; rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); if (rc != EOK) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); log_msg(LVL_DEBUG, "udp_sock_sendto: Failed to " "determine local address."); return; } socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4; log_msg(LVL_DEBUG, "Local IP address is %x", socket->assoc->ident.local.addr.ipv4); } assert(socket->assoc != NULL); for (index = 0; index < fragments; index++) { if (!async_data_write_receive(&wcallid, &length)) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, EINVAL); goto out; } if (length > UDP_FRAGMENT_SIZE) length = UDP_FRAGMENT_SIZE; rc = async_data_write_finalize(wcallid, buffer, length); if (rc != EOK) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); goto out; } urc = udp_uc_send(socket->assoc, fsockp, buffer, length, 0); switch (urc) { case UDP_EOK: rc = EOK; break; /* case TCP_ENOTEXIST: rc = ENOTCONN; break; case TCP_ECLOSING: rc = ENOTCONN; break; case TCP_ERESET: rc = ECONNABORTED; break;*/ default: assert(false); } if (rc != EOK) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); goto out; } } IPC_SET_ARG1(answer, 0); SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE); async_answer_2(callid, EOK, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer)); fibril_mutex_unlock(&socket->lock); out: if (addr != NULL) free(addr); }
int mesh_start_listening(Socket *mesh_listen_socket, uint16_t mesh_listen_socket_port, SocketCreateAllocatedFunction create_allocated) { int phase = 0; struct addrinfo *resolved_address = NULL; const char *address = config_get_option_value("listen.address")->string; log_info("Opening mesh listen socket (P: %u)", mesh_listen_socket_port); resolved_address = socket_hostname_to_address(address, mesh_listen_socket_port); // Currently no IPv6 support for mesh. if(resolved_address->ai_family == AF_INET6) { log_error("Mesh gateway does not support IPv6"); goto CLEANUP; } if (resolved_address == NULL) { log_error("Could not resolve mesh listen address '%s' (P: %u): %s (%d)", address, mesh_listen_socket_port, get_errno_name(errno), errno); goto CLEANUP; } phase = 1; // Create socket. if (socket_create(mesh_listen_socket) < 0) { log_error("Could not create mesh listen socket: %s (%d)", get_errno_name(errno), errno); goto CLEANUP; } phase = 2; if (socket_open(mesh_listen_socket, resolved_address->ai_family, resolved_address->ai_socktype, resolved_address->ai_protocol) < 0) { log_error("Could not open %s mesh listen socket: %s (%d)", network_get_address_family_name(resolved_address->ai_family, false), get_errno_name(errno), errno); goto CLEANUP; } #ifndef _WIN32 /* * On Unix the SO_REUSEADDR socket option allows to rebind sockets in * CLOSE-WAIT state. this is a desired effect. On Windows SO_REUSEADDR * allows to rebind sockets in any state. This is dangerous. Therefore, * don't set SO_REUSEADDR on Windows. Sockets can be rebound in CLOSE-WAIT * state on Windows by default. */ if (socket_set_address_reuse(mesh_listen_socket, true) < 0) { log_error("Could not enable address-reuse mode for mesh listen socket: %s (%d)", get_errno_name(errno), errno); goto CLEANUP; } #endif // Bind socket and start to listen. if (socket_bind(mesh_listen_socket, resolved_address->ai_addr, resolved_address->ai_addrlen) < 0) { log_error("Could not bind %s mesh listen socket to (A: %s, P: %u): %s (%d)", network_get_address_family_name(resolved_address->ai_family, true), address, mesh_listen_socket_port, get_errno_name(errno), errno); goto CLEANUP; } if (socket_listen(mesh_listen_socket, 10, create_allocated) < 0) { log_error("Could not listen to %s mesh socket (A: %s, P: %u): %s (%d)", network_get_address_family_name(resolved_address->ai_family, true), address, mesh_listen_socket_port, get_errno_name(errno), errno); goto CLEANUP; } log_info("Mesh gateway started listening on (A: %s, P: %u, F: %s)", address, mesh_listen_socket_port, network_get_address_family_name(resolved_address->ai_family, true)); if(event_add_source(mesh_listen_socket->base.handle, EVENT_SOURCE_TYPE_GENERIC, EVENT_READ, mesh_handle_accept, mesh_listen_socket) < 0) { goto CLEANUP; } phase = 3; freeaddrinfo(resolved_address); CLEANUP: switch(phase) { // No breaks, all cases fall through intentionally. case 2: socket_destroy(mesh_listen_socket); case 1: freeaddrinfo(resolved_address); default: break; } return phase == 3 ? 0 : -1; }
static int network_open_server_socket(Socket *server_socket, uint16_t port, SocketCreateAllocatedFunction create_allocated) { int phase = 0; const char *address = config_get_option_value("listen.address")->string; struct addrinfo *resolved_address = NULL; bool dual_stack; log_debug("Opening server socket on port %u", port); // resolve listen address // FIXME: bind to all returned addresses, instead of just the first one. // requires special handling if IPv4 and IPv6 addresses are returned // and dual-stack mode is enabled resolved_address = socket_hostname_to_address(address, port); if (resolved_address == NULL) { log_error("Could not resolve listen address '%s' (port: %u): %s (%d)", address, port, get_errno_name(errno), errno); goto cleanup; } phase = 1; // create socket if (socket_create(server_socket) < 0) { log_error("Could not create socket: %s (%d)", get_errno_name(errno), errno); goto cleanup; } phase = 2; if (socket_open(server_socket, resolved_address->ai_family, resolved_address->ai_socktype, resolved_address->ai_protocol) < 0) { log_error("Could not open %s server socket: %s (%d)", network_get_address_family_name(resolved_address->ai_family, false), get_errno_name(errno), errno); goto cleanup; } if (resolved_address->ai_family == AF_INET6) { dual_stack = config_get_option_value("listen.dual_stack")->boolean; if (socket_set_dual_stack(server_socket, dual_stack) < 0) { log_error("Could not %s dual-stack mode for IPv6 server socket: %s (%d)", dual_stack ? "enable" : "disable", get_errno_name(errno), errno); goto cleanup; } } #ifndef _WIN32 // on Unix the SO_REUSEADDR socket option allows to rebind sockets in // CLOSE-WAIT state. this is a desired effect. on Windows SO_REUSEADDR // allows to rebind sockets in any state. this is dangerous. therefore, // don't set SO_REUSEADDR on Windows. sockets can be rebound in CLOSE-WAIT // state on Windows by default. if (socket_set_address_reuse(server_socket, true) < 0) { log_error("Could not enable address-reuse mode for server socket: %s (%d)", get_errno_name(errno), errno); goto cleanup; } #endif // bind socket and start to listen if (socket_bind(server_socket, resolved_address->ai_addr, resolved_address->ai_addrlen) < 0) { log_error("Could not bind %s server socket to '%s' on port %u: %s (%d)", network_get_address_family_name(resolved_address->ai_family, true), address, port, get_errno_name(errno), errno); goto cleanup; } if (socket_listen(server_socket, 10, create_allocated) < 0) { log_error("Could not listen to %s server socket bound to '%s' on port %u: %s (%d)", network_get_address_family_name(resolved_address->ai_family, true), address, port, get_errno_name(errno), errno); goto cleanup; } log_debug("Started listening to '%s' (%s) on port %u", address, network_get_address_family_name(resolved_address->ai_family, true), port); if (event_add_source(server_socket->base.handle, EVENT_SOURCE_TYPE_GENERIC, EVENT_READ, network_handle_accept, server_socket) < 0) { goto cleanup; } phase = 3; freeaddrinfo(resolved_address); cleanup: switch (phase) { // no breaks, all cases fall through intentionally case 2: socket_destroy(server_socket); case 1: freeaddrinfo(resolved_address); default: break; } return phase == 3 ? 0 : -1; }