示例#1
0
文件: mhttp.c 项目: sreekotay/cxs
int main(int argc, char *argv[])
{
    mdnsd d;
    mdnsdr r;
    struct message m;
    unsigned long int ip;
    unsigned short int port;
    struct timeval *tv;
    int bsize, ssize = sizeof(struct sockaddr_in);
    unsigned char buf[MAX_PACKET_LEN];
    struct sockaddr_in from, to;
    fd_set fds;
    int s;
    unsigned char *packet, hlocal[256], nlocal[256];
    int len = 0;
    xht h;

    if(argc < 4) { printf("usage: mhttp 'unique name' 12.34.56.78 80 '/optionalpath'\n"); return; }

    ip = inet_addr(argv[2]);
    port = atoi(argv[3]);
    printf("Announcing .local site named '%s' to %s:%d and extra path '%s'\n",argv[1],inet_ntoa(ip),port,argv[4]);

    signal(SIGINT,done);
    signal(SIGHUP,done);
    signal(SIGQUIT,done);
    signal(SIGTERM,done);
    pipe(_zzz);
    _d = d = mdnsd_new(1,1000);
    if((s = msock()) == 0) { printf("can't create socket: %s\n",strerror(errno)); return 1; }

    sprintf(hlocal,"%s._http._tcp.local.",argv[1]);
    sprintf(nlocal,"http-%s.local.",argv[1]);
    r = mdnsd_shared(d,"_http._tcp.local.",QTYPE_PTR,120);
    mdnsd_set_host(d,r,hlocal);
    r = mdnsd_unique(d,hlocal,QTYPE_SRV,600,con,0);
    mdnsd_set_srv(d,r,0,0,port,nlocal);
    r = mdnsd_unique(d,nlocal,QTYPE_A,600,con,0);
    mdnsd_set_raw(d,r,(unsigned char *)&ip,4);
    r = mdnsd_unique(d,hlocal,16,600,con,0);
    h = xht_new(11);
    if(argc == 5 && argv[4] && strlen(argv[4]) > 0) xht_set(h,"path",argv[4]);
    packet = sd2txt(h, &len);
    xht_free(h);
    mdnsd_set_raw(d,r,packet,len);
    free(packet);

    while(1)
    {
        tv = mdnsd_sleep(d);
        FD_ZERO(&fds);
        FD_SET(_zzz[0],&fds);
        FD_SET(s,&fds);
        select(s+1,&fds,0,0,tv);

        // only used when we wake-up from a signal, shutting down
        if(FD_ISSET(_zzz[0],&fds)) read(_zzz[0],buf,MAX_PACKET_LEN);

        if(FD_ISSET(s,&fds))
        {
            while((bsize = recvfrom(s,buf,MAX_PACKET_LEN,0,(struct sockaddr*)&from,&ssize)) > 0)
            {
                bzero(&m,sizeof(struct message));
                message_parse(&m,buf);
                mdnsd_in(d,&m,(unsigned long int)from.sin_addr.s_addr,from.sin_port);
            }
            if(bsize < 0 && errno != EAGAIN) { printf("can't read from socket %d: %s\n",errno,strerror(errno)); return 1; }
        }
        while(mdnsd_out(d,&m,&ip,&port))
        {
            bzero(&to, sizeof(to));
            to.sin_family = AF_INET;
            to.sin_port = port;
            to.sin_addr.s_addr = ip;
            if(sendto(s,message_packet(&m),message_packet_len(&m),0,(struct sockaddr *)&to,sizeof(struct sockaddr_in)) != message_packet_len(&m))  { printf("can't write to socket: %s\n",strerror(errno)); return 1; }
        }
        if(_shutdown) break;
    }

    mdnsd_shutdown(d);
    mdnsd_free(d);
    return 0;
}
static void test_publish_on_interface(TestInstanceServer *instance, MDDIface_t iface)
{
    mdnsd d = instance->mdnsd;
    mdnsdr r;
    char *host_local = NULL;
    char *service_local = NULL;
    char *domain_local = NULL;
    unsigned char *packet = NULL;
    int ttl = 60;
    int len = 0;

    len = strlen(instance->publish_host_name) + strlen(".local.") + 1;
    host_local = malloc(len);
    sprintf(host_local, "%s.local.", instance->publish_host_name);
    host_local[len - 1] = '\0';

    len = strlen("_") + strlen(instance->publish_service_name) + strlen("._tcp.local.") + 1;
    service_local = malloc(len);
    sprintf(service_local, "_%s._tcp.local.", instance->publish_service_name);
    service_local[len - 1] = '\0';

    len = strlen(instance->publish_host_name) + strlen(".") + strlen(service_local) + 1;
    domain_local = malloc(len);
    sprintf(domain_local, "%s.%s", instance->publish_host_name, service_local);
    domain_local[len - 1] = '\0';

    if (instance->publish_max_rinterval > 0) {
        ttl = (instance->publish_max_rinterval * 2);
    }

    // add PTR
    r = mdnsd_shared(d, service_local, QTYPE_PTR, ttl, iface, _append_txt_cb, instance);
    mdnsd_set_host(d, r, domain_local);

    // add SRV
    r = mdnsd_unique(d, domain_local, QTYPE_SRV, ttl, iface, _publish_conflict_cb, instance);
    mdnsd_set_srv(d, r, 0, 0, instance->publish_service_port, host_local); // Priority = 0, Weight = 0

    // add ip address (A, AAAA)
    if (iface.addr.family == MDDNet_INET) {
        r = mdnsd_unique(d, host_local, QTYPE_A, ttl, iface, _publish_conflict_cb, instance);
        mdnsd_set_raw(d, r, (char *)&iface.addr.ip.ipv4, 4); // Set ipv4 address
    } else if (iface.addr.family == MDDNet_INET6) {
        r = mdnsd_unique(d, host_local, QTYPE_AAAA, ttl, iface, _publish_conflict_cb, instance);
        mdnsd_set_raw(d, r, (char *)&iface.addr.ip.ipv6, 16); // Set ipv6 address
    }

    // add TXT
    if (instance->publish_txt_xht != NULL) {
        r = mdnsd_unique(d, domain_local, QTYPE_TXT, ttl, iface, _publish_conflict_cb, instance);
        packet = sd2txt(instance->publish_txt_xht, &len);
        mdnsd_set_raw(d, r, (char *)packet, len);
        free(packet);
    } else {
        // create a null txt entry
        r = mdnsd_unique(d, domain_local, QTYPE_TXT, ttl, iface, _publish_conflict_cb, instance);
        mdnsd_set_raw(d, r, NULL, 0);
    }

    mdnsd_repeat_publish(instance->mdnsd, instance->publish_max_rinterval);

    free(host_local);
    free(service_local);
    free(domain_local);
}