static int tryudpsend(struct silly_socket *ss, struct cmdpacket *cmd) { struct socket *s = checksocket(ss, cmd->u.udpsend.sid); uint8_t *data = cmd->u.udpsend.data; size_t sz = cmd->u.udpsend.size; const struct sockaddr *addr = &cmd->u.udpsend.to; if (s == NULL) { silly_free(data); return 0; } assert(s->protocol == PROTOCOL_UDP); if (s->type == STYPE_SOCKET) //udp client need no address addr = NULL; if (wlist_empty(s)) {//try send ssize_t n = sendudp(s->fd, data, sz, addr); if (n == -1 || n >= 0) { //occurs error or send ok silly_free(data); return 0; } assert(n == -2); //EAGAIN wlist_append(s, data, 0, sz, addr); } else { wlist_append(s, data, 0, sz, addr); } return 0; }
static int trysend(struct silly_socket *ss, struct cmdpacket *cmd) { struct socket *s = checksocket(ss, cmd->u.send.sid); uint8_t *data = cmd->u.send.data; size_t sz = cmd->u.send.size; if (s == NULL) { silly_free(data); return 0; } if (wlist_empty(s)) {//try send ssize_t n = sendn(s->fd, data, sz); if (n < 0) { silly_free(data); report_close(ss, s, errno); delsocket(ss, s); return -1; } else if (n < sz) { wlist_append(s, data, n, sz, NULL); sp_write_enable(ss->spfd, s->fd, s, 1); } else { assert(n == sz); silly_free(data); } } else { wlist_append(s, data, 0, sz, NULL); } return 0; }
int silly_socket_udpsend(int sid, uint8_t *buff, size_t sz, const char *addr, size_t addrlen) { struct cmdpacket cmd; struct socket *s = checksocket(SSOCKET, sid); if (s == NULL) { silly_free(buff); return -1; } assert(s->protocol = PROTOCOL_UDP); assert(s->type == STYPE_UDPBIND || s->type == STYPE_SOCKET); if (s->type == STYPE_UDPBIND && addr == NULL) { fprintf(stderr, "[socket] udpsend udpbind socket must specify dest addr\n"); return -1; } cmd.type = 'U'; cmd.u.udpsend.sid = sid; cmd.u.udpsend.data= buff; cmd.u.udpsend.size = sz; if (s->type == STYPE_UDPBIND) {//udp bind socket need sendto address assert(addrlen == sizeof(cmd.u.udpsend.to)); memcpy(&cmd.u.udpsend.to, addr, sizeof(cmd.u.udpsend.to)); } pipe_blockwrite(SSOCKET->ctrlsendfd, &cmd); return 0; }
static int set80211priv(const char *dev, int op, void *data, int len, int show_err) { struct iwreq iwr; checksocket(); memset(&iwr, 0, sizeof(iwr)); strncpy(iwr.ifr_name, dev, IFNAMSIZ); if (len < IFNAMSIZ) { /* * Argument data fits inline; put it there. */ memcpy(iwr.u.name, data, len); } else { /* * Argument data too big for inline transfer; setup a * parameter block instead; the kernel will transfer * the data for the driver. */ iwr.u.data.pointer = data; iwr.u.data.length = len; } if (ioctl(s, op, &iwr) < 0) { if (show_err) { static const char *opnames[] = { IOCTL_ERR(IEEE80211_IOCTL_SETPARAM), IOCTL_ERR(IEEE80211_IOCTL_GETPARAM), IOCTL_ERR(IEEE80211_IOCTL_SETMODE), IOCTL_ERR(IEEE80211_IOCTL_GETMODE), IOCTL_ERR(IEEE80211_IOCTL_SETWMMPARAMS), IOCTL_ERR(IEEE80211_IOCTL_GETWMMPARAMS), IOCTL_ERR(IEEE80211_IOCTL_SETCHANLIST), IOCTL_ERR(IEEE80211_IOCTL_GETCHANLIST), IOCTL_ERR(IEEE80211_IOCTL_CHANSWITCH), IOCTL_ERR(IEEE80211_IOCTL_GETCHANINFO), IOCTL_ERR(IEEE80211_IOCTL_SETOPTIE), IOCTL_ERR(IEEE80211_IOCTL_GETOPTIE), IOCTL_ERR(IEEE80211_IOCTL_SETMLME), IOCTL_ERR(IEEE80211_IOCTL_SETKEY), IOCTL_ERR(IEEE80211_IOCTL_DELKEY), IOCTL_ERR(IEEE80211_IOCTL_ADDMAC), IOCTL_ERR(IEEE80211_IOCTL_DELMAC), IOCTL_ERR(IEEE80211_IOCTL_WDSADDMAC), IOCTL_ERR(IEEE80211_IOCTL_WDSDELMAC), }; if (IEEE80211_IOCTL_SETPARAM <= op && op <= IEEE80211_IOCTL_SETCHANLIST) perror(opnames[op - SIOCIWFIRSTPRIV]); else perror("ioctl[unknown???]"); } return -1; } return 0; }
int silly_socket_close(int sid) { struct cmdpacket cmd; struct socket *s = checksocket(SSOCKET, sid); if (s == NULL) return -1; cmd.type = 'K'; cmd.u.close.sid = sid; pipe_blockwrite(SSOCKET->ctrlsendfd, &cmd); return 0; }
static int tryclose(struct silly_socket *ss, struct cmdpacket *cmd) { struct socket *s = checksocket(ss, cmd->u.close.sid); if (s == NULL) return -1; if (wlist_empty(s)) { //already send all the data, directly close it delsocket(ss, s); return 0; } else { s->type = STYPE_HALFCLOSE; return -1; } }
int silly_socket_send(int sid, uint8_t *buff, size_t sz) { struct cmdpacket cmd; struct socket *s = checksocket(SSOCKET, sid); if (s == NULL) { silly_free(buff); return -1; } if (sz == 0) { silly_free(buff); return -1; } cmd.type = 'S'; cmd.u.send.sid = sid; cmd.u.send.data = buff; cmd.u.send.size = sz; pipe_blockwrite(SSOCKET->ctrlsendfd, &cmd); return 0; }