Subscribed unsubscribe Subscribe Subscribe

美人ゴルフ用サーバ

もうすっかり時期を逃した感があるけど、とりあえず書いてしまったので貼っときます。

美人ゴルフをするのに、実在するwww.bijint.comのサーバにアクセスするのは、とてもよくないことになるかもしれませんよね!!
なので練習用のサーバを書きましたよ東條さん!!

これをコンパイルして (log()使ってるので-lm必要、あとsockaddrの構造の違いでLinuxでしか動かない可能性大普通にPPC Mac OS Xでも動きました)、53番ポートと80番ポートを開ける権限で

./server [JPEG画像ファイル名]

みたいにして起動すると、ローカルで動くHTTPサーバもどきとDNSサーバもどきになります。

DNSに関しては、あらゆるドメイン名の正引きに対して127.0.0.1が返ってくるようになっているので、/etc/resolv.confに127.0.0.1をnameserverとして設定したりするといいですね。

HTTPに関しては、ブラウザでhttp://localhost/[任意のパス]を叩くとコマンドラインに指定した画像が返ってくることを確認できますよ!!

ちなみに中身ですが、もちろんHTTPプロトコルやDNSプロトコルをちゃんとまじめにハンドルしているということはなく、HTTPについてはCRLFが2連続で続く部分までを読み捨ててからレスポンスを返すということを、DNSに関しては受信したデータの先頭2バイト (query ID) だけをとって捨ててます。

EAGAINとerrno使う都合で#includeを入れないといけなかったのでワンライナーにならなかったのが心残りです。

#include <errno.h>
typedef char c;typedef int i;i sprintf(c*,c*,...);i socket();i close();i bind(i,i*,i);i read(i,c*,i);i write(i,c*,i);i***gethostbyname(c*);c*strstr(c*,c*);void*malloc();i open(c*,...);i recvfrom(i,c*,i,i,i*,i*);i sendto(i,c*,i,i,i*,i);i fcntl();i select(i,i*,i*,i*,i*);i listen();i setsockopt();i htonl();i signal();i strlen(c*);double log(double);i main(i e,c**y){i a=socket(2,1,6),o=socket(2,2,17),b[]={htonl(0x02000050),0,0,0},d=0,f,g,h=0,j,k[32]={a,o},l,n,p=0,r,t[65536][4],(*v)[4]=t,z;c *s,m[512]=" \r\n\r\nHTTP/1.0 200 OK\r\nContent-Type: image/jpeg\r\nContent-Length: %d\r\n\r",q[300000],u[]="\0\0\201\200\0\1\0\1\0\0\0\0\3www\6bijint\3com\0\0\1\0\1\300\f\0\1\0\1\0\0\2X\0\4\x7f\x00\x00\x01";if(!--e)return 0;l=strlen(m)+9;f=read(e=open(*++y,0),q+l,sizeof(q)-l),s=q+9-(i)(log(f)/log(10)),s[sprintf(s,m,f)]='\n',l+=f;close(e);signal(13,1);for(e=32;--e>=0;)k[e]=fcntl(f,4,z=setsockopt(f=k[e],65535,4,q,4)?setsockopt(f,1,2,q,4),2048:4),d|=1<<f,p=f>p?f:p;bind(a,b,16);b[0]=htonl(0x02000035);bind(o,b,16);listen(a,5);for(;;){f=d&~1;g=h;select(p+1,&f,&g,0,0);for(e=0;f>>=1,++e<32;)(f&1)&&(e==a&&(j=accept(a,0,0))&&(j>31?close(j):fcntl(j,4,z)?close(j):(d|=1<<j,k[j]=1,p=j>p?j:p))||(e==o)&&(n=16,recvfrom(o,m,512,0,b,&n)>0?**v=b[0],(*v)[1]=b[1],(*v)[2]=m[0],(*v)[3]=m[1],v++,h|=1<<e:1)||(r=k[e])&&(n=read(e,m,1),(k[e]=n<0?errno!=EAGAIN?0:r:(n?(r=r<5?s[r]!=*m?1:r+1:r)>4?d^=1<<e,h|=1<<e,r:r:0))||(close(e),d&=~(1<<e),h&=~(1<<e),p=log(d)/log(2))));for(e=0;g>>=1,++e<32;)(g&1)&&(e==o)&&(--v>=t?u[0]=(*v)[2],u[1]=(*v)[3],n=16,sendto(e,u,48,0,*v,n):(v++,h^=1<<e))||((r=k[e])>4)&&(n=write(e,s+r,l-r),(k[e]=n<0?errno!=EAGAIN?0:r:n&&(r+=n)<l?r:0)||(close(e),d&=~(1<<e),h&=~(1<<e),p=log(d)/log(2)));}}