static void update_address(const char *type, ea_t addr) { char tmp[100]; #ifdef __EA64__ qsnprintf(tmp, 100-1, "set%s 0x%llx", type, addr); #else qsnprintf(tmp, 100-1, "set%s 0x%x", type, addr); #endif ws_send(tmp); }
void send_init() { char buf[BUF_MAX]; int buf_l; buf_l = sprintf(buf, "init %d", my_port); printf("Sending %.*s to %s:%d\n", buf_l, buf, server_addr, server_port); ws_send(server_addr, server_port, buf, buf_l); }
bool loop() { char buf[1024]; int buf_l, in_l; buf_l = sprintf(buf, "msg %d ", my_id); if(scanf(" %1024[^\n]%n", buf+buf_l, &in_l) == EOF) return false; ws_send(server_addr, server_port, buf, buf_l+in_l); return true; }
static void recv_cb(char *addr, int port, char *buf, int buf_l) { printf("(%s:%d) -> %.*s\n", addr, port, buf_l, buf); /* buf -> init <id> <port> */ if(buf[0] == 'i' && buf[1] == 'n' && buf[2] == 'i' && buf[3] == 't') { int id, port; sscanf(buf+4, "%d", &port); id = nodes_l++; strcpy(nodes[id].addr, addr); nodes[id].port = port; buf_l = sprintf(buf, "ok %d", id); ws_send(addr,port, buf, buf_l); printf("added node %d (%s:%d)\n", id, addr, port); return; } /* buf -> msg <id> <channel> <data> */ if(buf[0] == 'm' && buf[1] == 's' && buf[2] == 'g') //msg { int id, i; sscanf(buf+3, " %d", &id); printf("Received msg from %d\n", id); for(i = 0; i < nodes[id].edges_l; i++) { printf("Redirecting to %s:%d\n", nodes[id].edges[i]->addr, nodes[id].edges[i]->port); ws_send(nodes[id].edges[i]->addr,nodes[id].edges[i]->port, buf, buf_l); } } }
static int inline ws_send_close(struct tcp_connection *con) { uint16_t code; int len; char *buf; if (WS_CODE(con)) { code = htons(WS_CODE(con)); len = sizeof(uint16_t); } else { len = 0; } buf = (char *)&code; return ws_send(con, con->fd, WS_OP_CLOSE, buf, len); }
/** * Multicasts message to all client in the list. * * @param type(ws_list *) l [List containing clients] * @param type(ws_message *) m [Message structure, that will be sent] */ void list_multicast_all(ws_list *l, ws_message *m) { ws_client *p; pthread_mutex_lock(&l->lock); p = l->first; if (p == NULL) { pthread_mutex_unlock(&l->lock); return; } do { ws_send(p, m); p = p->next; } while (p != NULL); pthread_mutex_unlock(&l->lock); }
ws_ctx_t *do_handshake(int sock) { char handshake[4096], response[4096], sha1[29], trailer[17]; char *scheme, *pre; headers_t *headers; int len, ret, i, offset; ws_ctx_t * ws_ctx; // Peek, but don't read the data len = recv(sock, handshake, 1024, MSG_PEEK); handshake[len] = 0; if (len == 0) { handler_msg("ignoring empty handshake\n"); return NULL; } else if (bcmp(handshake, "<policy-file-request/>", 22) == 0) { len = recv(sock, handshake, 1024, 0); handshake[len] = 0; handler_msg("sending flash policy response\n"); send(sock, POLICY_RESPONSE, sizeof(POLICY_RESPONSE), 0); return NULL; } else if ((bcmp(handshake, "\x16", 1) == 0) || (bcmp(handshake, "\x80", 1) == 0)) { // SSL if (!settings.cert) { handler_msg("SSL connection but no cert specified\n"); return NULL; } else if (access(settings.cert, R_OK) != 0) { handler_msg("SSL connection but '%s' not found\n", settings.cert); return NULL; } ws_ctx = alloc_ws_ctx(); ws_socket_ssl(ws_ctx, sock, settings.cert, settings.key); if (! ws_ctx) { return NULL; } scheme = "wss"; handler_msg("using SSL socket\n"); } else if (settings.ssl_only) { handler_msg("non-SSL connection disallowed\n"); return NULL; } else { ws_ctx = alloc_ws_ctx(); ws_socket(ws_ctx, sock); if (! ws_ctx) { return NULL; } scheme = "ws"; handler_msg("using plain (not SSL) socket\n"); } offset = 0; for (i = 0; i < 10; i++) { len = ws_recv(ws_ctx, handshake+offset, 4096); if (len == 0) { handler_emsg("Client closed during handshake\n"); return NULL; } offset += len; handshake[offset] = 0; if (strstr(handshake, "\r\n\r\n")) { break; } usleep(10); } //handler_msg("handshake: %s\n", handshake); if (!parse_handshake(ws_ctx, handshake)) { handler_emsg("Invalid WS request\n"); return NULL; } headers = ws_ctx->headers; if (ws_ctx->hybi > 0) { handler_msg("using protocol HyBi/IETF 6455 %d\n", ws_ctx->hybi); gen_sha1(headers, sha1); sprintf(response, SERVER_HANDSHAKE_HYBI, sha1, "base64"); } else { if (ws_ctx->hixie == 76) { handler_msg("using protocol Hixie 76\n"); gen_md5(headers, trailer); pre = "Sec-"; } else { handler_msg("using protocol Hixie 75\n"); trailer[0] = '\0'; pre = ""; } sprintf(response, SERVER_HANDSHAKE_HIXIE, pre, headers->origin, pre, scheme, headers->host, headers->path, pre, "base64", trailer); } //handler_msg("response: %s\n", response); ws_send(ws_ctx, response, strlen(response)); return ws_ctx; }
int ws_req_write(struct tcp_connection *con, int fd, char *buf, int len) { return ws_send(con, fd, WS_OP_TEXT, buf, len); }
int inline ws_send_pong(struct tcp_connection *con, struct ws_req *req) { return ws_send(con, con->fd, WS_OP_PONG, req->tcp.body, req->tcp.content_len); }
void* loop_io(void* p) { int ee = *(int*)(p); epoll_event ev, events[EVENT_QUEUE]; char in[IO_BUFFER + 100]; char out[IO_BUFFER + 100]; while (1) { int n = epoll_wait(epoll[ee], events, EVENT_QUEUE, -1); for (int i = 0; i < n; i++) { int f = events[i].data.fd; int& g = fd_status[f]; echo("thr %d con %d evn %d val %d src %d sta %d ", ee, event_count[ee], i, events[i].events, f, g); if (events[i].events & EPOLLIN) { int r = recv(f, in, sizeof(in), 0); if (r <= 0) { if (r == 0) echo("\x1b[0;31mclose %d\n\x1b[0m", f); else echo("\x1b[0;31merror %d\n\x1b[0m", f); close_fd(ee, f); continue; } echo("recv %d BYTEs\n", r); if (g <= 2) { in[r - 2] = 0; echo("\x1b[0;34m%s\x1b[0m", in); } else { in[r] = 0; for (int j = 0; j < r; j++) { echo("%02x ", (unsigned char)(in[j])); } out("\n"); if (((BYTE)in[1]) > 128) echo("\x1b[0;34m%s\x1b[0m\n", ws_decode(in)); else { echo("\x1b[0;31mclose %d\n\x1b[0m", f); close_fd(ee, f); } } if (g == 0) { if ((in[0] != 'G') || (in[1] != 'E') || (in[2] != 'T') || (in[3] != ' ') || (in[4] != '/')) goto _baad_req_; if (strstr(in, "Sec-WebSocket-Version: 13")) { char* c = strstr(in, "Sec-WebSocket-Key: "); if (!c) goto _baad_req_; c += 19; *(c + 24) = 0; ws_hash(c, fd_hash[f]); g = 2; } else { if (in[5] == ' ') g = 1; else goto _baad_req_; } if (g > 0) { ev.data.fd = f; ev.events = EPOLLIN | EPOLLOUT | EPOLLET; epoll_ctl(epoll[ee], EPOLL_CTL_MOD, f, &ev); goto _good_req_; } _baad_req_: g = -1; _good_req_: g = g; } if (g <= 0) { echo("bad request \x1b[0;31mclose %d\n\x1b[0m", f); close_fd(ee, f); } } if (events[i].events & EPOLLOUT) { int r = 0; if (g == 1) r = send(f, index_response, index_response_size, 0); else if (g == 2) { strncpy(response_101 + response_101_size - 32, fd_hash[f], 28); r = send(f, response_101, response_101_size, 0); g = 3; } else if (g == 3) { r = ws_send(f, "Hello!", out); g = 4; } else continue; echo("send %d BYTEs\n", r); } } } return 0; }
ws_ctx_t *do_handshake(int sock, bool* useHixie) { char handshake[4096], response[4096], trailer[17], hashDataB64[256]; char *scheme, *pre; headers_t headers; int len, i; u_char hashTemp[5]; ws_ctx_t * ws_ctx; SHA1Context sha1context; ws_ctx = ws_socket(sock); // Peek, but don't read the data len = ws_recv(ws_ctx, handshake, 1024); if (len < 1) { handler_msg("recv error %d in do_handshake\n", WSAGetLastError()); } handshake[len] = 0; if (len == 0) { handler_msg("ignoring empty handshake\n"); return NULL; } else if (bcmp(handshake, "<policy-file-request/>", 22) == 0) { handshake[len] = 0; handler_msg("sending flash policy response\n"); send(sock, policy_response, sizeof(policy_response) - 1, 0); return NULL; } else if ((bcmp(handshake, "\x16", 1) == 0) || (bcmp(handshake, "\x80", 1) == 0)) { // SSL if (!settings.cert) { handler_msg("SSL connection but no cert specified\n"); return NULL; } else if (access(settings.cert, R_OK) != 0) { handler_msg("SSL connection but '%s' not found\n", settings.cert); return NULL; } //ws_ctx = ws_socket_ssl(sock, settings.cert, settings.key); if (! ws_ctx) { return NULL; } scheme = "wss"; handler_msg("using SSL socket\n"); } else if (settings.ssl_only) { handler_msg("non-SSL connection disallowed\n"); return NULL; } else { ws_ctx = ws_socket(sock); if (! ws_ctx) { return NULL; } scheme = "ws"; handler_msg("using plain (not SSL) socket\n"); } //len = ws_recv(ws_ctx, handshake, 4096); if (len == 0) { handler_emsg("Client closed during handshake\n"); return NULL; } else if (len == -1) { return ws_ctx; } handshake[len] = 0; if (!parse_handshake(handshake, &headers)) { handler_emsg("Invalid WS request\n"); return NULL; } if (headers.version[0] != '\0') { //strcpy((char*)headers.key1, (const char *)"dGhlIHNhbXBsZSBub25jZQ=="); strncat(headers.key1, websocket_GUID, strlen(websocket_GUID)); SHA1Reset(&sha1context); //sha1context.Length_High = 0; //sha1context.Length_Low = strlen(headers.key1); SHA1Input(&sha1context, (const unsigned char*)&(headers.key1), strlen(headers.key1)); SHA1Result(&sha1context); for (i = 0; i < 5; i++) { hashTemp[i * 4] = ((u_char*)sha1context.Message_Digest)[i * 4 + 3]; hashTemp[i * 4 + 1] = ((u_char*)sha1context.Message_Digest)[i * 4 + 2]; hashTemp[i * 4 + 2] = ((u_char*)sha1context.Message_Digest)[i * 4 + 1]; hashTemp[i * 4 + 3] = ((u_char*)sha1context.Message_Digest)[i * 4]; } b64_ntop((const u_char*)&hashTemp, 5 * sizeof(int), (char*)&hashDataB64, 256); //b64_pton((const char*)sha1context.Message_Digest, (u_char*)&hashDataB64, 256); sprintf(response, server_handshake_hybi, headers.upgrade, headers.connection, hashDataB64); handler_msg("response: %s\n", response); ws_send(ws_ctx, response, strlen(response)); *useHixie = FALSE; return ws_ctx; } if (headers.key3[0] != '\0') { gen_md5(&headers, trailer); pre = "Sec-"; handler_msg("using protocol version 76\n"); } else { trailer[0] = '\0'; pre = ""; handler_msg("using protocol version 75\n"); } sprintf(response, server_handshake, pre, headers.origin, pre, scheme, headers.host, headers.path, "", trailer); handler_msg("response: %s\n", response); ws_send(ws_ctx, response, strlen(response)); return ws_ctx; }