LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { netPriv * priv; pixel_t * buffer; uint16_t buf[5]; coord_t x, y; #if GDISP_DONT_WAIT_FOR_NET_DISPLAY if (!(g->flags & GDISP_FLG_CONNECTED)) return; #else while(!(g->flags & GDISP_FLG_CONNECTED)) gfxSleepMilliseconds(200); #endif // Make everything relative to the start of the line buffer = g->p.ptr; buffer += g->p.x2*g->p.y1; priv = g->priv; buf[0] = GNETCODE_BLIT; buf[1] = g->p.x; buf[2] = g->p.y; buf[3] = g->p.cx; buf[4] = g->p.cy; MUTEX_ENTER; sendpkt(priv->netfd, buf, 5); for(y = 0; y < g->p.cy; y++, buffer += g->p.x2 - g->p.cx) { for(x = 0; x < g->p.cx; x++, buffer++) { buf[0] = gdispColor2Native(buffer[0]); sendpkt(priv->netfd, buf, 1); } } MUTEX_EXIT; }
static DECLARE_THREAD_FUNCTION(NetThread, param) { GEventMouse *pem; uint16_t cmd[2]; uint16_t lbuttons; coord_t lx, ly; (void) param; // Initialize the mouse and the listener. geventListenerInit(&gl); geventAttachSource(&gl, ginputGetMouse(0), GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); lbuttons = 0; lx = ly = -1; while(1) { // Get a (mouse) event pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE); if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) continue; // Nothing to do if the socket is not open if (netfd == (SOCKET)-1) continue; // Nothing to do if the mouse data has not changed if (lx == pem->x && ly == pem->y && lbuttons == pem->current_buttons) continue; // Transfer mouse data that has changed if (lx != pem->x) { lx = pem->x; cmd[0] = GNETCODE_MOUSE_X; cmd[1] = lx; sendpkt(cmd, 2); } if (ly != pem->y) { ly = pem->y; cmd[0] = GNETCODE_MOUSE_Y; cmd[1] = ly; sendpkt(cmd, 2); } // We always send the buttons as it also acts as a mouse sync signal lbuttons = pem->current_buttons; cmd[0] = GNETCODE_MOUSE_B; cmd[1] = lbuttons; sendpkt(cmd, 2); } return 0; }
//这个函数打开TCP端口SON_PORT, 等待来自本地SIP进程的进入连接. //在本地SIP进程连接之后, 这个函数持续接收来自SIP进程的sendpkt_arg_t结构, 并将报文发送到重叠网络中的下一跳. //如果下一跳的节点ID为BROADCAST_NODEID, 报文应发送到所有邻居节点. void waitSIP() { int listenfd, connfd; int option = 1; struct sockaddr_in caddr, saddr; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("Listen is Wrong !!!!!!!\n"); exit(2); } if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0){ printf("Error!!!!!\n"); exit(2); } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(SON_PORT); bind(listenfd, (struct sockaddr*)&saddr, sizeof(saddr)); listen(listenfd, 2); socklen_t len = sizeof(caddr); connfd = accept(listenfd, (struct sockaddr*)&caddr, &len); close(listenfd); sip_conn = connfd; sip_pkt_t* pkt = (sip_pkt_t *)malloc(sizeof(sip_pkt_t)); int *nextNode = (int *)malloc(sizeof(int)); while(1){ if(getpktToSend(pkt, nextNode,sip_conn) > 0){ if(*nextNode == BROADCAST_NODEID){ int j = 0; while(j < neighNum){ sendpkt(pkt, nt[j].conn); j ++; } } else{ int j = 0; while(j < neighNum){ if(*nextNode == nt[j].nodeID){ sendpkt(pkt, nt[j].conn); j ++; } } } } } }
int main(int argc, char **argv) { char *ename = basename(argv[0]); uint8_t msg[PCKT_LEN]; memset(msg, 0, sizeof msg); msg[0] = MODE_LOCK; // c**k blocked if(strcmp(ename, "lock") == 0) { msg[1] = LOCK_LOCKED; } else if(strcmp(ename, "unlock") == 0) { msg[1] = LOCK_UNLOCKED; } else { printf("have a nice day ;)\n"); return 0; } sendpkt(msg); time_t rightnow = time(NULL); struct tm *stamp = localtime(&rightnow); char timestamp[100]; // probably big enough... struct passwd *userentry = getpwuid(getuid()); strftime(timestamp, sizeof timestamp, "%a %F %T", stamp); logline("%s := Door %s by %s\n", timestamp, msg[1] == LOCK_LOCKED ? "locked" : "unlocked", userentry->pw_name); return 0; }
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { netPriv * priv; uint16_t buf[3]; color_t data; #if GDISP_DONT_WAIT_FOR_NET_DISPLAY if (!(g->flags & GDISP_FLG_CONNECTED)) return 0; #else while(!(g->flags & GDISP_FLG_CONNECTED)) gfxSleepMilliseconds(200); #endif priv = g->priv; buf[0] = GNETCODE_READ; buf[1] = g->p.x; buf[2] = g->p.y; MUTEX_ENTER; sendpkt(priv->netfd, buf, 3); MUTEX_EXIT; // Now wait for a reply while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_READ) gfxSleepMilliseconds(1); data = gdispNative2Color(priv->data[1]); g->flags &= ~GDISP_FLG_HAVEDATA; return data; }
/* * Reset the network connection by sending an RST packet, print an error * message to standard output, and exit. */ void reset(int fd) { fprintf(stderr, "protocol error encountered... resetting connection\n"); sendpkt(fd, RMTP_TYPE_RST, 0, 0, 0, 0); exit(0); }
//这个函数打开TCP端口SON_PORT, 等待来自本地SIP进程的进入连接. //在本地SIP进程连接之后, 这个函数持续接收来自SIP进程的sendpkt_arg_t结构, 并将报文发送到重叠网络中的下一跳. //如果下一跳的节点ID为BROADCAST_NODEID, 报文应发送到所有邻居节点. void waitSIP() { struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int listenfd; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SON_PORT); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); listen(listenfd, 20); sip_conn = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); //recv pkt from sip and send sip_pkt_t pkt; int nextNode, conn; while(1){ if(getpktToSend(&pkt,&nextNode,sip_conn) == 1){ if (pkt.header.type == SIP){ if((conn = getConnByID(nextNode)) >= 0){ if(sendpkt(&pkt,conn) < 0) printf("Error in send pkt to Nbr\n"); } else { printf("Wrong Node id nextNode = %d\n",nextNode); } } else if (pkt.header.type == ROUTE_UPDATE){ int nbr_num = topology_getNbrNum(); int i; for (i = 0; i < nbr_num; i++){ if (nt[i].conn >= 0 && sendpkt(&pkt, nt[i].conn) < 0){ printf("Error in send route update pkt to Nbr\n"); } } } } } printf("Error in getpktToSend\n"); }
//send out heartbeat (alive) messages to the tracker to keep its online status void *Alive(void *arg) { ptp_peer_t pkt; p2T_pkt_set(&pkt, 0, NULL, KEEP_ALIVE, NULL, myIP, PEER_PORT, 0, NULL); while (1) { sleep(ALIVE_INTERVAL); if (sendpkt(tracker_conn, &pkt) < 0) { printf("%s KEEP_ALIVE sending failed!\n", peer_trace); return NULL; } } }
// Sends a key/value pair out on the specified net socket. // Accepts: file descriptor, key, value, length of value (needed because it might be binary) // Returns: whether it was done sanely bool hashhash::sendfile(int sfd, const char *filename, const char *data, size_t dlen) { // We should be careful; this is the maximum number of bytes we can have. int maxdatabytes = MAX_PACKET_LEN - 3; int numpkt = (int)ceil((double)dlen/maxdatabytes); int lastpkt = dlen % maxdatabytes; sendpkt(sfd, OPC_HRZ, filename, -1); for(int i = 0; i < numpkt; ++i) { int databytes = maxdatabytes; if(lastpkt != 0 && i == numpkt - 1) { databytes = lastpkt; } if(!sendpkt(sfd, OPC_STF, (data + i*maxdatabytes), databytes)) { return false; } } if(!sendpkt(sfd, OPC_STF, NULL, 0)) return false; return true; }
LLDSPEC void gdisp_lld_flush(GDisplay *g) { netPriv * priv; uint16_t buf[1]; #if GDISP_DONT_WAIT_FOR_NET_DISPLAY if (!(g->flags & GDISP_FLG_CONNECTED)) return; #else while(!(g->flags & GDISP_FLG_CONNECTED)) gfxSleepMilliseconds(200); #endif priv = g->priv; buf[0] = GNETCODE_FLUSH; MUTEX_ENTER; sendpkt(priv->netfd, buf, 1); MUTEX_EXIT; }
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { netPriv * priv; uint16_t buf[4]; #if GDISP_DONT_WAIT_FOR_NET_DISPLAY if (!(g->flags & GDISP_FLG_CONNECTED)) return; #else while(!(g->flags & GDISP_FLG_CONNECTED)) gfxSleepMilliseconds(200); #endif priv = g->priv; buf[0] = GNETCODE_PIXEL; buf[1] = g->p.x; buf[2] = g->p.y; buf[3] = gdispColor2Native(g->p.color); MUTEX_ENTER; sendpkt(priv->netfd, buf, 4); MUTEX_EXIT; }
/* ** xmt() */ void xmt( xmt_ctx * xctx ) { SOCKET sock = xctx->sock; struct dns_ctx *dctx = xctx->spkt->dctx; sent_pkt * spkt = xctx->spkt; sockaddr_u * dst = &spkt->addr; struct timeval tv_xmt; struct pkt x_pkt; size_t pkt_len; int sent; if (0 != gettimeofday(&tv_xmt, NULL)) { msyslog(LOG_ERR, "xmt: gettimeofday() failed: %m"); exit(1); } tv_xmt.tv_sec += JAN_1970; pkt_len = generate_pkt(&x_pkt, &tv_xmt, dctx->key_id, dctx->key); sent = sendpkt(sock, dst, &x_pkt, pkt_len); if (sent) { /* Save the packet we sent... */ memcpy(&spkt->x_pkt, &x_pkt, min(sizeof(spkt->x_pkt), pkt_len)); spkt->stime = tv_xmt.tv_sec - JAN_1970; TRACE(2, ("xmt: %lx.%6.6u %s %s\n", (u_long)tv_xmt.tv_sec, (u_int)tv_xmt.tv_usec, dctx->name, stoa(dst))); } else { dec_pending_ntp(dctx->name, dst); } return; }
LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) { netPriv * priv; uint16_t buf[6]; #if GDISP_DONT_WAIT_FOR_NET_DISPLAY if (!(g->flags & GDISP_FLG_CONNECTED)) return; #else while(!(g->flags & GDISP_FLG_CONNECTED)) gfxSleepMilliseconds(200); #endif priv = g->priv; buf[0] = GNETCODE_SCROLL; buf[1] = g->p.x; buf[2] = g->p.y; buf[3] = g->p.cx; buf[4] = g->p.cy; buf[5] = g->p.y1; MUTEX_ENTER; sendpkt(priv->netfd, buf, 6); MUTEX_EXIT; }
static event_t * get_packet_v(rtmp_t *r, uint8_t *data, int size, int64_t dts, media_pipe_t *mp) { uint8_t flags; uint8_t type = 0; enum AVCodecID id; int d = 0; event_t *e; if(r->r->m_read.flags & RTMP_READ_SEEKING) return NULL; if(size < 2) return NULL; flags = *data++; size--; switch(flags & 0xf) { case 7: type = *data++; size--; id = AV_CODEC_ID_H264; if(size < 3) return NULL; d = (AMF_DecodeInt24((char *)data) + 0xff800000) ^ 0xff800000; data += 3; size -= 3; break; case 4: type = *data++; size--; id = AV_CODEC_ID_VP6F; break; default: return NULL; } if(r->vcodec == NULL) { media_codec_params_t mcp = {0}; switch(id) { case AV_CODEC_ID_H264: if(type != 0 || size < 0) return NULL; mcp.extradata = data; mcp.extradata_size = size; break; case AV_CODEC_ID_VP6F: if(size < 1) return NULL; mcp.extradata = data; mcp.extradata_size = size; break; default: abort(); } mcp.width = r->width; mcp.height = r->height; r->vcodec = media_codec_create(id, 0, NULL, NULL, &mcp, mp); return NULL; } int skip = 0; // r->last_video_dts = dts; int64_t pts = 1000LL * (dts + d); dts = 1000LL * dts; if(d < 0 || dts <= r->seekpos_video) { skip = 1; r->in_seek_skip = 1; } else if(r->in_seek_skip) { skip = 2; r->in_seek_skip = 0; } else { r->seekpos_video = dts; } e = sendpkt(r, &r->mp->mp_video, r->vcodec, dts, pts, data, size, skip, MB_VIDEO, r->vframeduration, 1); return e; }
/* The heart of (S)NTP, exchange NTP packets and compute values to correct the local clock */ int on_wire ( struct addrinfo *host, struct addrinfo *bcast ) { char addr_buf[INET6_ADDRSTRLEN]; register int try; SOCKET sock; struct key *pkt_key = NULL; int key_id = 0; struct timeval tv_xmt; struct pkt x_pkt; int error, rpktl, handle_pkt_res; if (ENABLED_OPT(AUTHENTICATION)) { key_id = (int) atol(OPT_ARG(AUTHENTICATION)); get_key(key_id, &pkt_key); } for (try=0; try<5; try++) { memset(&r_pkt, 0, sizeof rbuf); error = GETTIMEOFDAY(&tv_xmt, (struct timezone *)NULL); tv_xmt.tv_sec += JAN_1970; #ifdef DEBUG printf("sntp on_wire: Current time sec: %i msec: %i\n", (unsigned int) tv_xmt.tv_sec, (unsigned int) tv_xmt.tv_usec); #endif if (bcast) { create_socket(&sock, (sockaddr_u *)bcast->ai_addr); rpktl = recv_bcst_pkt(sock, &r_pkt, sizeof rbuf, (sockaddr_u *)bcast->ai_addr); closesocket(sock); } else { int pkt_len = generate_pkt(&x_pkt, &tv_xmt, key_id, pkt_key); create_socket(&sock, (sockaddr_u *)host->ai_addr); sendpkt(sock, (sockaddr_u *)host->ai_addr, &x_pkt, pkt_len); rpktl = recvpkt(sock, &r_pkt, sizeof rbuf, &x_pkt); closesocket(sock); } handle_pkt_res = handle_pkt(rpktl, &r_pkt, host); if (handle_pkt_res < 1) return handle_pkt_res; } getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST); msyslog(LOG_DEBUG, "Received no useable packet from %s!", addr_buf); return -1; } /* Compute the 8 bits for li_vn_mode */ void set_li_vn_mode ( struct pkt *spkt, char leap, char version, char mode ) { if (leap > 3) { msyslog(LOG_DEBUG, "set_li_vn_mode: leap > 3 using max. 3"); leap = 3; } if (mode > 7) { msyslog(LOG_DEBUG, "set_li_vn_mode: mode > 7, using client mode 3"); mode = 3; } spkt->li_vn_mode = leap << 6; spkt->li_vn_mode |= version << 3; spkt->li_vn_mode |= mode; } /* set_time corrects the local clock by offset with either settimeofday() or by default * with adjtime()/adjusttimeofday(). */ int set_time( double offset ) { struct timeval tp; if (ENABLED_OPT(SETTOD)) { GETTIMEOFDAY(&tp, NULL); tp.tv_sec += (long)offset; tp.tv_usec += 1e6 * (offset - (long)offset); NORMALIZE_TIMEVAL(tp); if (SETTIMEOFDAY(&tp, NULL) < 0) { msyslog(LOG_ERR, "Time not set: settimeofday(): %m"); return -1; } return 0; } tp.tv_sec = (long)offset; tp.tv_usec = 1e6 * (offset - (long)offset); NORMALIZE_TIMEVAL(tp); if (ADJTIMEOFDAY(&tp, NULL) < 0) { msyslog(LOG_ERR, "Time not set: adjtime(): %m"); return -1; } return 0; }
main(int argc, char *argv[]) { setbuf(stdout, NULL); int sock; // check usage if (argc != 4) { fprintf(stderr, "usage : %s <username> <server_ip_address> <5945>\n", argv[0]); exit(1); } // get hooked on to the server sock = hooktoserver(argv[1], argv[2], atoi(argv[3])); if (sock == -1) exit(1); fflush(stdout); // Initialize FDs to zero. // Assign Input FD to client Fds. // Assign socked FD to client Fds. fd_set clientfds, tempfds; FD_ZERO(&clientfds); FD_ZERO(&tempfds); FD_SET(sock, &clientfds); FD_SET(0, &clientfds); while (1) { // Use tempfds as it will be overwritten on select call // We want clientfds to keep track of all connected fds. tempfds = clientfds; if (select(FD_SETSIZE, &tempfds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } // For every fd in the list, if the fd is set, check if // that is socket fd. If so, then it means that it we // received some message from server. It can be a message // from different client or server death. Also if the fd // is 0, it means there is some input from the user. // Read that input and send it to the server. int fd; for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd,&tempfds)) { if (fd == sock) { Packet *pkt; pkt = recvpkt(sock); if (!pkt) { // server killed, exit fprintf(stderr, "Server closed the connection.\n"); exit(1); } // display the text if (pkt->type == EMAIL_MSG_TO_CLIENT) { printf("New email received !\n>> %s\n", pkt->text); }else if(pkt->type == WELCOME_MSG){ // Received welcome message. Print it. printf(">> %s\n", pkt->text); // Send username to client. char msg[MAXMSGLEN]; strcpy(msg, argv[1]); // fprintf(stderr, "user: %s", msg); sendpkt(sock, USER_NAME, strlen(msg) + 1, msg); }else if(pkt->type == SERVER_ERROR) { printf(">> %s\n", pkt->text); } else{ fprintf(stderr, "error: unexpected reply from server\n"); exit(1); } // free the message freepkt(pkt); } if (fd == 0) { char msg[MAXMSGLEN]; if (!fgets(msg, MAXMSGLEN, stdin)) exit(0); if (strncmp(msg, QUIT_STRING, strlen(QUIT_STRING)) == 0) { sendpkt(sock, CLOSE_CON, 0, NULL); break; } char * pch1, *pch2, *user, *ipaddr; pch1 = strstr(msg, " "); pch2 = strstr(msg, "@"); if (pch1 == NULL || pch2 == NULL) { fprintf(stderr, "error: invalid e-mail format.\nsyntax: <recp_user>@<ip_addr> <mesg>\n"); break; } if (pch1 < pch2) { fprintf(stderr, "error: user name cannot contain spaces.\n"); fprintf(stderr, "error: invalid e-mail format.\nsyntax: <recp_user>@<ip_addr> <mesg>\n"); break; } user = (char *) malloc((strlen(msg) - strlen(pch2) + 1)*sizeof(char)); strncpy(user, msg, (strlen(msg) - strlen(pch2))*sizeof(char)); user[strlen(msg) - strlen(pch2)] = '\0'; // fprintf(stderr, "client: user: %s", user); if(strcmp(user,"") == 0) { fprintf(stderr, "error: no username entered.\n"); free(user); break; } ipaddr = (char *) malloc( (strlen(pch2) - strlen(pch1))* sizeof(char)); strncpy(ipaddr, msg + strlen(user) + 1, (strlen(pch2) - strlen(pch1) - 1) * sizeof(char)); ipaddr[strlen(pch2) - strlen(pch1) - 1] = '\0'; // fprintf(stderr, "server: ip: %s", ipaddr); struct sockaddr_in sa; int result = inet_pton(AF_INET, ipaddr, &(sa.sin_addr)); if(result == 0){ fprintf(stderr, "error: invalid ip-address format.\nsyntax: <recp_user>@<ip_addr> <mesg>\n"); free(user); free(ipaddr); break; } char * mailmsg; mailmsg = (char *) malloc(strlen(pch1) * sizeof(char)); strncpy(mailmsg, msg + strlen(user) + strlen(ipaddr) + 2, (strlen(pch1) - 1) * sizeof(char)); mailmsg[strlen(pch1)-1] = '\0'; // It is okay to have empty body in the email message. if(strlen(mailmsg) > 80) { fprintf(stderr, "error: mail message length can be atmost 80 characters.\n"); free(user); free(ipaddr); free(mailmsg); break; } // fprintf(stderr, "server: mailmsg: %s", mailmsg); free(user); free(ipaddr); free(mailmsg); msg[strlen(msg) - 1] = '\0'; sendpkt(sock, EMAIL_MSG_TO_SERVER, strlen(msg) + 1, msg); } } } } }
/* * sendrequest - format and send a request packet * * Historically, ntpdc has used a fixed-size request packet regardless * of the actual payload size. When authenticating, the timestamp, key * ID, and digest have been placed just before the end of the packet. * With the introduction in late 2009 of support for authenticated * ntpdc requests using larger 20-octet digests (vs. 16 for MD5), we * come up four bytes short. * * To maintain interop while allowing for larger digests, the behavior * is unchanged when using 16-octet digests. For larger digests, the * timestamp, key ID, and digest are placed immediately following the * request payload, with the overall packet size variable. ntpd can * distinguish 16-octet digests by the overall request size being * REQ_LEN_NOMAC + 4 + 16 with the auth bit enabled. When using a * longer digest, that request size should be avoided. * * With the form used with 20-octet and larger digests, the timestamp, * key ID, and digest are located by ntpd relative to the start of the * packet, and the size of the digest is then implied by the packet * size. */ static int sendrequest( int implcode, int reqcode, int auth, u_int qitems, size_t qsize, char *qdata ) { struct req_pkt qpkt; size_t datasize; size_t reqsize; u_long key_id; l_fp ts; l_fp * ptstamp; int maclen; char * pass; memset(&qpkt, 0, sizeof(qpkt)); qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0); qpkt.implementation = (u_char)implcode; qpkt.request = (u_char)reqcode; datasize = qitems * qsize; if (datasize && qdata != NULL) { memcpy(qpkt.data, qdata, datasize); qpkt.err_nitems = ERR_NITEMS(0, qitems); qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize); } else { qpkt.err_nitems = ERR_NITEMS(0, 0); qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize); /* allow for optional first item */ } if (!auth || (keyid_entered && info_auth_keyid == 0)) { qpkt.auth_seq = AUTH_SEQ(0, 0); return sendpkt(&qpkt, req_pkt_size); } if (info_auth_keyid == 0) { key_id = getkeyid("Keyid: "); if (!key_id) { fprintf(stderr, "Invalid key identifier\n"); return 1; } info_auth_keyid = key_id; } if (!authistrusted(info_auth_keyid)) { pass = getpass_keytype(info_auth_keytype); if ('\0' == pass[0]) { fprintf(stderr, "Invalid password\n"); return 1; } authusekey(info_auth_keyid, info_auth_keytype, (u_char *)pass); authtrust(info_auth_keyid, 1); } qpkt.auth_seq = AUTH_SEQ(1, 0); if (info_auth_hashlen > 16) { /* * Only ntpd which expects REQ_LEN_NOMAC plus maclen * octets in an authenticated request using a 16 octet * digest (that is, a newer ntpd) will handle digests * larger than 16 octets, so for longer digests, do * not attempt to shorten the requests for downlevel * ntpd compatibility. */ if (REQ_LEN_NOMAC != req_pkt_size) return 1; reqsize = REQ_LEN_HDR + datasize + sizeof(*ptstamp); /* align to 32 bits */ reqsize = (reqsize + 3) & ~3; } else reqsize = req_pkt_size; ptstamp = (void *)((char *)&qpkt + reqsize); ptstamp--; get_systime(&ts); L_ADD(&ts, &delay_time); HTONL_FP(&ts, ptstamp); maclen = authencrypt(info_auth_keyid, (void *)&qpkt, reqsize); if (!maclen) { fprintf(stderr, "Key not found\n"); return 1; } else if (maclen != (info_auth_hashlen + sizeof(keyid_t))) { fprintf(stderr, "%d octet MAC, %lu expected with %lu octet digest\n", maclen, (u_long)(info_auth_hashlen + sizeof(keyid_t)), (u_long)info_auth_hashlen); return 1; } return sendpkt(&qpkt, reqsize + maclen); }
//这个函数打开TCP端口SON_PORT, 等待来自本地SIP进程的进入连接. //在本地SIP进程连接之后, 这个函数持续接收来自SIP进程的sendpkt_arg_t结构, 并将报文发送到重叠网络中的下一跳. //如果下一跳的节点ID为BROADCAST_NODEID, 报文应发送到所有邻居节点. void waitSIP() { int listenfd; socklen_t clilen; clilen = sizeof(struct sockaddr_in); struct sockaddr_in cliaddr, servaddr; memset(&cliaddr, 0, sizeof(cliaddr)); memset(&servaddr, 0, sizeof(servaddr)); listenfd = socket(AF_INET, SOCK_STREAM, 0); servaddr.sin_family = AF_INET; // servaddr.sin_addr.s_addr = INADDR_ANY; inet_aton("127.0.0.1", &servaddr.sin_addr); servaddr.sin_port = htons(SON_PORT); const int on = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(const int)); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); listen(listenfd, MAX_NODE_NUM); while (1) { // wait for sip connection memset(&cliaddr, 0, sizeof(struct sockaddr)); sip_conn = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); if (sip_conn == -1) { print_pos(); printf("ERROR: accept sip connection failed\n"); sleep(1); continue; } /* recv from sip and son forward start here */ // print_pos(); // printf("MSG: sip access ok, sip_conn = %d, begin to convey sip->son\n", sip_conn); sip_pkt_t tmp; int nNode, result; while (1){ memset(&tmp, 0, sizeof(sip_pkt_t)); result = getpktToSend(&tmp, &nNode, sip_conn); if(result == -1) { print_pos(); printf("ERROR: get pkt from sip failed\nMSG: Break loop wait another sip connect\n"); sleep(1); break; } // print_pos(); // printf("MSG: get sip_pkt_t to send ok, send to nbr...\n"); // if broad cast, send to every neighbor if (nNode == BROADCAST_NODEID){ int ct = topology_getNbrNum(); int i; for (i = 0; i < ct; i++){ // print_pos(); // printf("MSG: broadcast send to socket %d\n", nt[i].conn); result = sendpkt(&tmp, nt[i].conn); if (result == -1){ print_pos(); printf("ERROR: send pkt to broadcast failed\n"); continue; } } // printf("MSG: send sip_pkt_t to broadcast ok\n"); } else{ // others, send to next hop int destConn = getConnByNode(nNode); if (destConn == -1) { print_pos(); printf("ERROR: conn not set up\n"); } result = sendpkt(&tmp, destConn); if (result == -1){ printf("ERROR: send pkt to next node failed\n"); continue; } // printf("MSG: send sip_pkt_t to nbr ok, socket=%d\n", destConn); } } } }
//monitor a local file directory; send out updated file table to the tracker if any file changes in the local file directory void *FileMonitor(void *arg) { ptp_peer_t pkt; p2T_pkt_set(&pkt, 0, NULL, FILE_UPDATE, NULL, myIP, PEER_PORT, 0, NULL); //monitor a local file directory int fd; int wd; char buffer[BUF_LEN]; fd = inotify_init(); if (fd < 0) { perror("inotify_init"); } wd = inotify_add_watch(fd, ".", IN_MODIFY | IN_CREATE | IN_DELETE | IN_CLOSE_WRITE | IN_DELETE_SELF); int state = 0; int out = 0; while (out == 0) { int i = 0; int length = read(fd, buffer, BUF_LEN); if (length < 0) { perror("read"); } while (i < length) { struct inotify_event *event = (struct inotify_event *) &buffer[ i ]; if (event->len && event->name[0] != '.') { if (event->mask & IN_DELETE_SELF) { out = 1; break; } else if (event->mask & IN_DELETE) { pthread_mutex_lock(peer_file_table_mutex); if (event->mask & IN_ISDIR) { printf("The directory %s was deleted.\n", event->name); } else { printf("The file %s was deleted.\n", event->name); } filenode *p = fileTable_Exist(file_table, event->name, myIP); if (p != NULL) { // if the file is still in the table, that means the peer itself delete it instead of the tracker told it to fileTable_Delete(event->name, myIP); // then we need to send the updated table to the tracker if (sendpkt(tracker_conn, &pkt) < 0) { printf("%s updated local file table sending failed!\n", peer_trace); return NULL; } } pthread_mutex_unlock(peer_file_table_mutex); } else if (event->mask & IN_CREATE) { state = 2; //printf("create %s\n", event->name); } else if (event->mask & IN_MODIFY) { //printf("modify %s\n", event->name); if (state == 0) { state = 1; } } else if (event->mask & IN_CLOSE_WRITE) { //printf("close write %s\n", event->name); pthread_mutex_lock(peer_file_table_mutex); if (state == 2) { if (event->mask & IN_ISDIR) { printf("The directory %s was created.\n", event->name); } else { printf("The file %s was created.\n", event->name); } filenode tmp; memset(&tmp, 0, sizeof(filenode)); strcpy(tmp.filename, event->name); tmp.filesize = getFileSize(tmp.filename); if (tmp.filesize < 0) { state = 0; pthread_mutex_unlock(peer_file_table_mutex); continue; } tmp.timestamp = 0; strcpy(tmp.peerIP, myIP); // try to add this node into the local file table // if there's already such a node in the table, that means this file is downloaded // otherwise it's created filenode* p = fileTable_Exist(file_table, event->name, NULL); if (p == NULL) { // locally created a file fileTable_Add(&tmp, myIP); } else { if (strcmp(p->peerIP, myIP) != 0) { // newly downloaded strcpy(p->peerIP, myIP); } else { // vim version update p->filesize = getFileSize(event->name); p->timestamp = 0; } } printf("%s Updated local file table:\n", peer_trace); fileTable_Print(file_table); // either way we should send the updated table to the tracker if (sendpkt(tracker_conn, &pkt) < 0) { printf("%s updated local file table sending failed!\n", peer_trace); return NULL; } } else if (state == 1) { if (event->mask & IN_ISDIR) { printf("The directory %s was modified.\n", event->name); } else { printf("The file %s was modified.\n", event->name); } filenode *p = fileTable_Exist(file_table, event->name, NULL); if (p != NULL) { if (strcmp(p->peerIP, myIP) == 0) { // the file is modified locally, reset the size and the timestamp and send to the tracker p->filesize = getFileSize(event->name); p->timestamp = 0; } else { strcpy(p->peerIP, myIP); } printf("%s Updated local file table:\n", peer_trace); fileTable_Print(file_table); if (sendpkt(tracker_conn, &pkt) < 0) { printf("%s updated local file table sending failed!\n", peer_trace); return NULL; } } else { printf("I should not be here!\n"); } } state = 0; pthread_mutex_unlock(peer_file_table_mutex); } } i += EVENT_SIZE + event->len; } } (void) inotify_rm_watch(fd, wd); (void) close(fd); exit(0); }
void peer_main() { // initialize the tables tracker_conn = -1; fileTable_Initialize(); peerpeerTable_Initialize(); // initialize the mutex peer_file_table_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); peer_peer_table_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(peer_file_table_mutex, NULL); pthread_mutex_init(peer_peer_table_mutex, NULL); //register peer_stop signal(SIGINT,peer_stop); myIP = my_ip(); printf("%s Local ip address is %s\n", peer_trace, myIP); // try to connect to the tracker tracker_conn = connectToTracker(); if (-1 == tracker_conn) { printf("%s Can't connect to tracker", peer_trace); return; } printf("%s Connection to the tracker established.\n", peer_trace); ptp_peer_t pkt; p2T_pkt_set(&pkt, 0, NULL, REGISTER, NULL, myIP, PEER_PORT, 0, NULL); if (sendpkt(tracker_conn, &pkt) < 0) { printf("%s REGISTER sending failed!\n", peer_trace); peer_stop(); return; } // create the alive thread pthread_t alive_thread; pthread_create(&alive_thread, NULL, Alive, NULL); printf("%s Alive thread created.\n", peer_trace); // create a P2P Listen thread pthread_t p2p_listen_thread; pthread_create(&p2p_listen_thread, NULL, P2PListen, NULL); printf("%s p2p listen thread created.\n", peer_trace); // create a file monitor thread char dir_name[FILE_NAME_LEN]; printf("%s Please input the directory which you would like to monitor:", peer_trace); scanf("%s", dir_name); // create a loval file directory to monitor mkdir(dir_name, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); chdir(dir_name); DIR *dir = opendir("."); if (dir == NULL) { printf("%s The directory which you input is invalid.\n", peer_trace); peer_stop(); return; } struct dirent *entry; pthread_mutex_lock(peer_file_table_mutex); while ((entry = readdir(dir)) != NULL) { if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0) { continue; } filenode tmp; memset(&tmp, 0, sizeof(filenode)); strcpy(tmp.filename, entry->d_name); tmp.filesize = getFileSize(tmp.filename); if (tmp.filesize < 0) { continue; } tmp.timestamp = 0; strcpy(tmp.peerIP, myIP); fileTable_Add(&tmp, myIP); } pthread_mutex_unlock(peer_file_table_mutex); pthread_t file_monitor_thread; pthread_create(&file_monitor_thread, NULL, FileMonitor, (void *) "."); printf("%s file monitor thread created.\n", peer_trace); // int setup = 0; filenode *global_table; for (;;) { if (fileTable_Receive(tracker_conn, &global_table) < 0) { printf("%s Connection to the tracker is lost. Exiting...\n", peer_trace); break; } printf("%s Received a file table from the tracker:\n", peer_trace); fileTable_Print(global_table); pthread_mutex_lock(peer_file_table_mutex); // based on the global file table, update the local file table filenode *cur = global_table; while (cur != NULL) { if (cur != fileTable_Exist(global_table, cur->filename, NULL)) { // this file has been processed before cur = cur->next; continue; } filenode *tmp = fileTable_Exist(file_table, cur->filename, NULL); if (tmp == NULL) { // if our local file table doesn't have this file, should we add it? if (fileTable_Exist(global_table, cur->filename, myIP) != NULL) { // if this ip used to have the file in the global table, that means we just deleted locally, but the tracker hasn't updated it yet // thus we should not add this file, cause the delete action is the latest one cur = cur->next; continue; } else { // if this ip never has this file, we should add it fileTable_Add(cur, ""); Download(cur->filename, cur->filesize, global_table); } } // if out local file table has this file, should we update it? else { // if this file is newly created but hasn't been marked with a timestamp from the tracker if (tmp->timestamp == 0) { // filenode *p = fileTable_Exist(global_table, cur->filename, myIP); // if (p != NULL && p->timestamp == fileTable_latest(global_table, cur->filename)) { // // update the timestamp given from the tracker tmp->timestamp = cur->timestamp; // } // else { // // some peer created this new file with the same name first or updated it first // // then we shuold change our name // strcat(strcat(tmp->name, " from "), myIP); // } } else { if (difftime(tmp->timestamp, cur->timestamp) >= 0) { // this file is the latest one, do nothing cur = cur->next; continue; } else { // not the latest one // need to update //remove(cur->filename); //fileTable_Add(cur, myIP); tmp->filesize = cur->filesize; tmp->timestamp = cur->timestamp; memset(tmp->peerIP, 0, IP_LEN); Download(cur->filename, cur->filesize, global_table); } } } cur = cur->next; } // if (setup > 0) { // //traverse the local file table to see if there's anything need to be deleted cur = file_table; while (cur != NULL) { if (fileTable_Exist(global_table, cur->filename, NULL) == NULL/* && cur->timestamp != 0*/) { // the global table doesn't have this file and the timestamp used to be assigned by the tracker remove(cur->filename); fileTable_Delete(cur->filename, myIP); // what if we can't delete this file } cur = cur->next; } // } // setup++; printf("%s Updated local file table:\n", peer_trace); fileTable_Print(file_table); fileTable_Destroy(global_table); pthread_mutex_unlock(peer_file_table_mutex); } peer_stop(); }
//这个函数打开TCP端口SON_PORT, 等待来自本地SIP进程的进入连接. //在本地SIP进程连接之后, 这个函数持续接收来自SIP进程的sendpkt_arg_t结构, 并将报文发送到重叠网络中的下一跳. //如果下一跳的节点ID为BROADCAST_NODEID, 报文应发送到所有邻居节点. void waitSIP() { socklen_t clilen; int listenfd; //char buf[MAXLINE]; struct sockaddr_in cliaddr,servaddr; listenfd = socket(AF_INET,SOCK_STREAM,0); memset(&servaddr, 0, sizeof(struct sockaddr_in)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(SON_PORT); bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); listen(listenfd,MAX_NODE_NUM);//开始监听 clilen = sizeof(cliaddr); int connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); sip_conn = connfd; printf("IP linked\n"); while(1) { sip_pkt_t* pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t)); memset(pkt,0,sizeof(sip_pkt_t)); int nextNode = 0; // 如果成功接收sendpkt_arg_t结构, 返回1, 否则返回-1. if(getpktToSend(pkt,&nextNode,sip_conn)==1) { printf("in son ready to send:%d\n",pkt->header.src_nodeID); if(nextNode == BROADCAST_NODEID) { int i = 0; for(i = 0 ;i <topology_getNbrNum();i++) { printf("send to everyone!\n"); if(nt[i].conn == -1) { printf("%d sleep no more send to him\n",nt[i].nodeID); continue; } if(sendpkt(pkt, nt[i].conn) == 1) { printf("send to nextnode sucess! %d\n",nt[i].conn); } else { printf("send fail %d",i); } } } else { int i = 0; for(i = 0 ;i <topology_getNbrNum();i++) { if(nextNode == nt[i].nodeID) { break; } } if(i == topology_getNbrNum()) { printf("cant find next node!\n"); exit(0); } if(nt[i].conn == -1) { printf("%d sleep no more send to him\n",nt[i].nodeID); continue; } // 如果报文发送成功, 返回1, 否则返回-1. if(sendpkt(pkt, nt[i].conn) == 1) { printf("send to nextnode sucess!\n"); } else { printf("send to nextnode fail\n"); } } } else { printf("SIP stop!!!!!!!!!!!!!!!\n"); break; } } }
static event_t * get_packet_v(rtmp_t *r, uint8_t *data, size_t size, int64_t dts, media_pipe_t *mp) { uint8_t flags; uint8_t type = 0; enum CodecID id; int d = 0; event_t *e; if(r->r->m_read.flags & RTMP_READ_SEEKING) return NULL; if(size < 2) return NULL; flags = *data++; size--; switch(flags & 0xf) { case 7: type = *data++; size--; id = CODEC_ID_H264; if(size < 3) return NULL; d = (AMF_DecodeInt24((char *)data) + 0xff800000) ^ 0xff800000; data += 3; size -= 3; break; case 4: type = *data++; size--; id = CODEC_ID_VP6F; break; default: return NULL; } if(r->vcodec == NULL) { AVCodecContext *ctx; media_codec_params_t mcp = {0}; switch(id) { case CODEC_ID_H264: if(type != 0 || size < 0) return NULL; ctx = avcodec_alloc_context3(NULL); ctx->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(ctx->extradata, data, size); ctx->extradata_size = size; break; case CODEC_ID_VP6F: if(size < 1) return NULL; ctx = avcodec_alloc_context3(NULL); ctx->extradata = av_mallocz(1 + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(ctx->extradata, &type, 1); ctx->extradata_size = 1; break; default: abort(); } mcp.width = r->width; mcp.height = r->height; r->vcodec = media_codec_create(id, 0, NULL, ctx, &mcp, mp); return NULL; } int skip = 0; int64_t pts = 1000LL * (dts + d); dts = 1000LL * dts; if(d < 0 || dts < r->seekpos) { skip = 1; r->in_seek_skip = 1; } else if(r->in_seek_skip) { skip = 2; r->in_seek_skip = 0; } r->lastdts = dts; e = sendpkt(r, &r->mp->mp_video, r->vcodec, dts, pts, AV_NOPTS_VALUE, data, size, skip, MB_VIDEO, r->vframeduration); return e; }
static DECLARE_THREAD_FUNCTION(NetThread, param) { SOCKET_TYPE listenfd, fdmax, i, clientfd; socklen_t len; int leni; fd_set master, read_fds; struct sockaddr_in addr; GDisplay * g; netPriv * priv; (void)param; // Start the sockets layer StartSockets(); gfxSleepMilliseconds(100); // Make sure the thread has time to start. /* clear the master and temp sets */ FD_ZERO(&master); FD_ZERO(&read_fds); if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == (SOCKET_TYPE)-1) gfxHalt("GDISP: uGFXnet - Socket failed"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(GDISP_GFXNET_PORT); if (bind(listenfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) gfxHalt("GDISP: uGFXnet - Bind failed"); if (listen(listenfd, 10) == -1) gfxHalt("GDISP: uGFXnet - Listen failed"); /* add the listener to the master set */ FD_SET(listenfd, &master); /* keep track of the biggest file descriptor */ fdmax = listenfd; /* so far, it's this one*/ #if GDISP_GFXNET_BROKEN_LWIP_ACCEPT { #warning "Using GDISP_GFXNET_BROKEN_LWIP_ACCEPT limits the number of displays and the use of GFXNET. Avoid if possible!" len = sizeof(addr); if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1) gfxHalt("GDISP: uGFXnet - Accept failed"); // Look for a display that isn't connected for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) { // Ignore displays for other controllers #ifdef GDISP_DRIVER_LIST if (gvmt(g) != &GDISPVMT_uGFXnet) continue; #endif if (!(g->flags & GDISP_FLG_CONNECTED)) break; } // Was anything found? if (!g) { // No Just close the connection closesocket(clientfd); gfxHalt("GDISP: uGFXnet - Can't find display for connection"); return 0; } // Save the descriptor FD_SET(clientfd, &master); if (clientfd > fdmax) fdmax = clientfd; priv = g->priv; memset(priv, 0, sizeof(netPriv)); priv->netfd = clientfd; //printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1); // Send the initialisation data (2 words at a time) priv->data[0] = GNETCODE_INIT; priv->data[1] = GNETCODE_VERSION; sendpkt(priv->netfd, priv->data, 2); priv->data[0] = GDISP_SCREEN_WIDTH; priv->data[1] = GDISP_SCREEN_HEIGHT; sendpkt(priv->netfd, priv->data, 2); priv->data[0] = GDISP_LLD_PIXELFORMAT; priv->data[1] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0; MUTEX_ENTER; sendpkt(priv->netfd, priv->data, 2); MUTEX_EXIT; // The display is now working g->flags |= GDISP_FLG_CONNECTED; // Send a redraw all #if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER gdispGClear(g, gwinGetDefaultBgColor()); gwinRedrawDisplay(g, FALSE); #endif } #endif /* loop */ for(;;) { /* copy it */ read_fds = master; if (select(fdmax+1, &read_fds, 0, 0, 0) == -1) gfxHalt("GDISP: uGFXnet - Select failed"); // Run through the existing connections looking for data to be read for(i = 0; i <= fdmax; i++) { if(!FD_ISSET(i, &read_fds)) continue; // Handle new connections if(i == listenfd) { len = sizeof(addr); if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1) gfxHalt("GDISP: uGFXnet - Accept failed"); // Look for a display that isn't connected for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) { // Ignore displays for other controllers #ifdef GDISP_DRIVER_LIST if (gvmt(g) != &GDISPVMT_uGFXnet) continue; #endif if (!(g->flags & GDISP_FLG_CONNECTED)) break; } // Was anything found? if (!g) { // No Just close the connection closesocket(clientfd); //printf(New connection from %s on socket %d rejected as all displays are already connected\n", inet_ntoa(addr.sin_addr), clientfd); continue; } // Save the descriptor FD_SET(clientfd, &master); if (clientfd > fdmax) fdmax = clientfd; priv = g->priv; memset(priv, 0, sizeof(netPriv)); priv->netfd = clientfd; //printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1); // Send the initialisation data (2 words at a time) priv->data[0] = GNETCODE_INIT; priv->data[1] = GNETCODE_VERSION; sendpkt(priv->netfd, priv->data, 2); priv->data[0] = GDISP_SCREEN_WIDTH; priv->data[1] = GDISP_SCREEN_HEIGHT; sendpkt(priv->netfd, priv->data, 2); priv->data[0] = GDISP_LLD_PIXELFORMAT; priv->data[1] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0; MUTEX_ENTER; sendpkt(priv->netfd, priv->data, 2); MUTEX_EXIT; // The display is now working g->flags |= GDISP_FLG_CONNECTED; // Send a redraw all #if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER gdispGClear(g, gwinGetDefaultBgColor()); gwinRedrawDisplay(g, FALSE); #endif continue; } // Handle data from a client // Look for a display that is connected and the socket descriptor matches for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) { // Ignore displays for other controllers #ifdef GDISP_DRIVER_LIST if (gvmt(g) != &GDISPVMT_uGFXnet) continue; #endif priv = g->priv; if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == i) break; } if (!g) gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection"); if ((g->flags & GDISP_FLG_HAVEDATA)) { // The higher level is still processing the previous data. // Give it a chance to run by coming back to this data. gfxSleepMilliseconds(1); continue; } /* handle data from a client */ MUTEX_ENTER; if ((leni = recv(i, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) { // Socket closed or in error state MUTEX_EXIT; g->flags &= ~GDISP_FLG_CONNECTED; memset(priv, 0, sizeof(netPriv)); closesocket(i); FD_CLR(i, &master); continue; } MUTEX_EXIT; // Do we have a full reply yet priv->databytes += leni; if (priv->databytes < sizeof(priv->data)) continue; priv->databytes = 0; // Convert network byte or to host byte order priv->data[0] = ntohs(priv->data[0]); priv->data[1] = ntohs(priv->data[1]); // Process the data received switch(priv->data[0]) { #if GINPUT_NEED_MOUSE case GNETCODE_MOUSE_X: priv->mousex = priv->data[1]; break; case GNETCODE_MOUSE_Y: priv->mousey = priv->data[1]; break; case GNETCODE_MOUSE_B: priv->mousebuttons = priv->data[1]; // Treat the button event as the sync signal #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE ginputMouseWakeup(); #endif break; #endif case GNETCODE_CONTROL: case GNETCODE_READ: g->flags |= GDISP_FLG_HAVEDATA; break; case GNETCODE_KILL: gfxHalt("GDISP: uGFXnet - Display sent KILL command"); break; default: // Just ignore unrecognised data break; } } } return 0; }
//这个函数打开TCP端口SON_PORT, 等待来自本地SIP进程的进入连接. //在本地SIP进程连接之后, 这个函数持续接收来自SIP进程的sendpkt_arg_t结构, 并将报文发送到重叠网络中的下一跳. //如果下一跳的节点ID为BROADCAST_NODEID, 报文应发送到所有邻居节点. void waitSIP() { //你需要编写这里的代码. int nbrNum = topology_getNbrNum(); int listenfd=0; struct sockaddr_in servaddr,cliaddr; socklen_t clilen; if ((listenfd=socket(AF_INET, SOCK_STREAM,0))<0) { puts("create socket error!"); } servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(SON_PORT); const int on = 1; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); bind(listenfd,(struct sockaddr *)&servaddr, sizeof(servaddr)); puts("SON Wait For SIP Server Init Success!"); listen(listenfd,1); while(1){ sip_conn=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); puts("Accept SIP Process!"); int nextNode=0; sip_pkt_t* recv_seg=malloc(sizeof(sip_pkt_t)); memset(recv_seg,0,sizeof(sip_pkt_t)); while (1){ if (getpktToSend(recv_seg,&nextNode,sip_conn)!=1) //continue; break; if (nextNode==BROADCAST_NODEID){ //char *flags=malloc(nbrNum); //memset(flags,0,nbrNum); for (int i=0;i<nbrNum;i++) { if (sendpkt(recv_seg,nt[i].conn)==-1) { //flags[i]=1; } }/* for (int i=0;i<nbrNum;i++) { if (flags[i]==1) { forwardpktToSIP(build_failpkt(nt[i].nodeID),sip_conn); } } free(flags);*/ } else{ for (int i=0;i<nbrNum;i++) { if (nt[i].nodeID==nextNode) { if (sendpkt(recv_seg,nt[i].conn)==-1) { //forwardpktToSIP(build_failpkt(nt[i].nodeID),sip_conn); } break; } } } } printf("####SIP stop!! listening for next SIP\n"); close(sip_conn); } }
static event_t * get_packet_a(rtmp_t *r, uint8_t *data, size_t size, int64_t dts, media_pipe_t *mp) { uint8_t flags; uint8_t type = 0; enum CodecID id; if(r->r->m_read.flags & RTMP_READ_SEEKING) return NULL; if(size < 2) return NULL; flags = *data++; size--; switch(flags & 0xf0) { case 0xa0: id = CODEC_ID_AAC; type = *data++; size--; break; case 0x20: id = CODEC_ID_MP3; break; default: return NULL; } if(r->acodec == NULL) { AVCodecContext *ctx; int parse = 0; const char *fmt; switch(id) { case CODEC_ID_AAC: if(type != 0 || size < 0) return NULL; ctx = avcodec_alloc_context3(NULL); ctx->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(ctx->extradata, data, size); ctx->extradata_size = size; fmt = "AAC"; break; case CODEC_ID_MP3: ctx = avcodec_alloc_context3(NULL); parse = 1; fmt = "MP3"; break; default: abort(); } mp_add_track(mp->mp_prop_audio_tracks, NULL, "rtmp:1", fmt, fmt, NULL, NULL, NULL, 0); prop_set_string(mp->mp_prop_audio_track_current, "rtmp:1"); r->acodec = media_codec_create(id, parse, NULL, ctx, NULL, mp); return NULL; } media_codec_t *mc = r->acodec; dts *= 1000; if(dts < r->seekpos) return NULL; if(mc->parser_ctx == NULL) return sendpkt(r, &mp->mp_audio, mc, dts, dts, dts, data, size, 0, MB_AUDIO, 0); while(size > 0) { int outlen; uint8_t *outbuf; int rlen = av_parser_parse2(mc->parser_ctx, mc->codec_ctx, &outbuf, &outlen, data, size, dts, dts, AV_NOPTS_VALUE); if(outlen) { event_t *e = sendpkt(r, &mp->mp_audio, mc, mc->parser_ctx->dts, mc->parser_ctx->pts, mc->parser_ctx->dts, outbuf, outlen, 0, MB_AUDIO, 0); if(e != NULL) return e; } dts = AV_NOPTS_VALUE; data += rlen; size -= rlen; } return NULL; }
static event_t * get_packet_a(rtmp_t *r, uint8_t *data, int size, int64_t dts, media_pipe_t *mp) { uint8_t flags; uint8_t type = 0; enum AVCodecID id; if(r->r->m_read.flags & RTMP_READ_SEEKING) return NULL; if(size < 2) return NULL; flags = *data++; size--; switch(flags & 0xf0) { case 0xa0: id = AV_CODEC_ID_AAC; type = *data++; size--; break; case 0x20: id = AV_CODEC_ID_MP3; break; default: return NULL; } if(r->acodec == NULL) { media_codec_params_t mcp = {0}; int parse = 0; const char *fmt; switch(id) { case AV_CODEC_ID_AAC: if(type != 0 || size < 0) return NULL; mcp.extradata = data; mcp.extradata_size = size; fmt = "AAC"; break; case AV_CODEC_ID_MP3: parse = 1; fmt = "MP3"; break; default: abort(); } mp_add_track(mp->mp_prop_audio_tracks, NULL, "rtmp:1", fmt, fmt, NULL, NULL, NULL, 0, 1); prop_set_string(mp->mp_prop_audio_track_current, "rtmp:1"); r->acodec = media_codec_create(id, parse, NULL, NULL, &mcp, mp); return NULL; } media_codec_t *mc = r->acodec; dts *= 1000; if(dts <= r->seekpos_audio) return NULL; r->seekpos_audio = dts; if(mc->parser_ctx == NULL) return sendpkt(r, &mp->mp_audio, mc, dts, dts, data, size, 0, MB_AUDIO, 0, 0); while(size > 0) { int outlen; uint8_t *outbuf; int rlen = av_parser_parse2(mc->parser_ctx, mc->fmt_ctx, &outbuf, &outlen, data, size, dts, dts, AV_NOPTS_VALUE); if(outlen) { event_t *e = sendpkt(r, &mp->mp_audio, mc, mc->parser_ctx->dts, mc->parser_ctx->pts, outbuf, outlen, 0, MB_AUDIO, 0, 0); if(e != NULL) return e; } dts = AV_NOPTS_VALUE; data += rlen; size -= rlen; } return NULL; }
//这个函数打开TCP端口SON_PORT, 等待来自本地SIP进程的进入连接. //在本地SIP进程连接之后, 这个函数持续接收来自SIP进程的sendpkt_arg_t结构, 并将报文发送到重叠网络中的下一跳. //如果下一跳的节点ID为BROADCAST_NODEID, 报文应发送到所有邻居节点. void waitSIP() { int sockfd; struct sockaddr_in cli_addr, serv_addr; socklen_t clilen; if((sockfd = socket(AF_INET, SOCK_STREAM, 0))<0) { perror("Error create socket\n"); exit(-1); } const int one = 1; //port可以立即重新使用 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SON_PORT); if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0) { perror("Error bind\n"); exit(-1); } listen(sockfd, MAX_NODE_NUM); clilen = sizeof(cli_addr); while(1) { sip_conn = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen); sip_pkt_t* sip_pkt; int next; while(1) { sip_pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t)); memset(sip_pkt, 0, sizeof(sip_pkt_t)); if(getpktToSend(sip_pkt, &next, sip_conn)>0) { if(next == BROADCAST_NODEID) { int nbrnum = topology_getNbrNum(); int i = 0; for(i=0; i<nbrnum; i++) { //if(nt[i].conn > 0) { sendpkt(sip_pkt, nt[i].conn); //} //else { //printf("sendpkt conn<0, id: %d\n", nt[i].nodeID); //} } } else { if(sip_pkt->header.type == SIP) { printf("Receive stcp packet!\n"); } int nbrnum = topology_getNbrNum(); int i = 0; for(i=0; i<nbrnum; i++) { if(next == nt[i].nodeID) { printf("send message to node %d\n", next); sendpkt(sip_pkt, nt[i].conn); break; } } } } else { free(sip_pkt); close(sip_conn); break; } free(sip_pkt); } } return; }
LLDSPEC void gdisp_lld_control(GDisplay *g) { netPriv * priv; uint16_t buf[3]; bool_t allgood; #if GDISP_DONT_WAIT_FOR_NET_DISPLAY if (!(g->flags & GDISP_FLG_CONNECTED)) return; #else while(!(g->flags & GDISP_FLG_CONNECTED)) gfxSleepMilliseconds(200); #endif // Check if we might support the code switch(g->p.x) { case GDISP_CONTROL_ORIENTATION: if (g->g.Orientation == (orientation_t)g->p.ptr) return; break; case GDISP_CONTROL_POWER: if (g->g.Powermode == (powermode_t)g->p.ptr) return; break; case GDISP_CONTROL_BACKLIGHT: if (g->g.Backlight == (uint16_t)(int)g->p.ptr) return; if ((uint16_t)(int)g->p.ptr > 100) g->p.ptr = (void *)100; break; default: return; } // Send the command priv = g->priv; buf[0] = GNETCODE_CONTROL; buf[1] = g->p.x; buf[2] = (uint16_t)(int)g->p.ptr; MUTEX_ENTER; sendpkt(priv->netfd, buf, 3); MUTEX_EXIT; // Now wait for a reply while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_CONTROL) gfxSleepMilliseconds(1); // Extract the return status allgood = priv->data[1] ? TRUE : FALSE; g->flags &= ~GDISP_FLG_HAVEDATA; // Do nothing more if the operation failed if (!allgood) return; // Update the local stuff switch(g->p.x) { case GDISP_CONTROL_ORIENTATION: switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: case GDISP_ROTATE_180: g->g.Width = GDISP_SCREEN_WIDTH; g->g.Height = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_90: case GDISP_ROTATE_270: g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; default: return; } g->g.Orientation = (orientation_t)g->p.ptr; break; case GDISP_CONTROL_POWER: g->g.Powermode = (powermode_t)g->p.ptr; break; case GDISP_CONTROL_BACKLIGHT: g->g.Backlight = (uint16_t)(int)g->p.ptr; break; } }
/** * Our main function. * There are two prototypes - one for systems with a command line and one for embedded systems without one. */ int main(proto_args) { uint16_t cmd[5]; unsigned cnt; // Initialize and clear the display gfxInit(); font = gdispOpenFont("UI2"); // Open the connection gdispDrawStringBox(0, 0, gdispGetWidth(), gdispGetHeight(), "Connecting to host...", font, White, justifyCenter); StartSockets(); netfd = doConnect(cmd_args); if (netfd == (SOCKET_TYPE)-1) gfxHalt("Could not connect to the specified server"); gdispClear(Black); // Get the initial packet from the host if (!getpkt(cmd, 2)) goto alldone; if (cmd[0] != GNETCODE_INIT || cmd[1] != GNETCODE_VERSION) gfxHalt("Oops - The protocol doesn't look like one we understand"); // Get the rest of the initial arguments if (!getpkt(cmd, 4)) goto alldone; // cmd[] = width, height, pixelformat, hasmouse // We will ignore size mismatches but the pixel format must match if (cmd[2] != GDISP_PIXELFORMAT) gfxHalt("Oops - The remote display is using a different pixel format to us.\nTry defining GDISP_PIXELFORMAT in your gfxconf.h file."); #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE // Start the mouse thread if needed if (cmd[3]) gfxThreadClose(gfxThreadCreate(waNetThread, sizeof(waNetThread), HIGH_PRIORITY, NetThread, 0)); #endif // Process incoming instructions while(getpkt(cmd, 1)) { switch(cmd[0]) { case GNETCODE_FLUSH: gdispFlush(); break; case GNETCODE_PIXEL: if (!getpkt(cmd, 3)) goto alldone; // cmd[] = x, y, color gdispDrawPixel(cmd[0], cmd[1], cmd[2]); break; case GNETCODE_FILL: if (!getpkt(cmd, 5)) goto alldone; // cmd[] = x, y, cx, cy, color gdispFillArea(cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); break; case GNETCODE_BLIT: if (!getpkt(cmd, 4)) goto alldone; // cmd[] = x, y, cx, cy - Followed by cx * cy pixels gdispStreamStart(cmd[0],cmd[1],cmd[2],cmd[3]); for(cnt = (unsigned)cmd[2] * cmd[3]; cnt; cnt--) { if (!getpkt(cmd, 1)) goto alldone; gdispStreamColor(cmd[0]); } gdispStreamStop(); break; #if GDISP_NEED_PIXELREAD case GNETCODE_READ: if (!getpkt(cmd, 2)) goto alldone; // cmd[] = x, y - Response is GNETCODE_READ,color cmd[1] = gdispGetPixelColor(cmd[0], cmd[1]); cmd[0] = GNETCODE_READ; if (!sendpkt(cmd, 2)) goto alldone; break; #endif #if GDISP_NEED_SCROLL case GNETCODE_SCROLL: if (!getpkt(cmd, 5)) goto alldone; // cmd[] = x, y, cx, cy, lines gdispVerticalScroll(cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], Black); break; #endif case GNETCODE_CONTROL: if (!getpkt(cmd, 2)) goto alldone; // cmd[] = what,data - Response is GNETCODE_CONTROL, 0x0000 (fail) or GNETCODE_CONTROL, 0x0001 (success) gdispControl(cmd[0], (void *)(unsigned)cmd[1]); switch(cmd[0]) { case GDISP_CONTROL_ORIENTATION: cmd[1] = (uint16_t)gdispGetOrientation() == cmd[1] ? 1 : 0; break; case GDISP_CONTROL_POWER: cmd[1] = (uint16_t)gdispGetPowerMode() == cmd[1] ? 1 : 0; break; case GDISP_CONTROL_BACKLIGHT: cmd[1] = (uint16_t)gdispGetBacklight() == cmd[1] ? 1 : 0; break; default: cmd[1] = 0; break; } cmd[0] = GNETCODE_CONTROL; if (!sendpkt(cmd, 2)) goto alldone; break; default: gfxHalt("Oops - The host has sent invalid commands"); break; } } alldone: closesocket(netfd); gfxHalt("Connection closed"); return 0; }
void pinghandler() { char pkt[15]; sprintf(pkt, "#pingreply#:%d", cliid); sendpkt(gservaddr, pkt, SERVPORT); }