紅葉&温泉ツーリング

連日のお仕事で心が癒やしを求めていたので紅葉眺めながら温泉入ってきた。

山の上の方は、もう結構葉に色が着いてて紅葉のピークって感じ。 f:id:hkou:20161105102957j:plain

蓼科温泉 小斉の湯(たてしなおんせん こさいのゆ)

以前は旅館として経営されてたそうですが、今は日帰り入浴のみやっているそうです。 f:id:hkou:20161105121446j:plain

内湯。温度は結構熱め。匂いはそこまでしなかったけど少しぬるっとした泉質でなかなか良かった。
入ったときは先客が居たけれどすぐに出てしまったので貸し切り状態。一応今日は休日なんだけど、お客さん結構少なく感じた。こちらとしては独占できるから良いんだけど。 f:id:hkou:20161105123515j:plain

露天風呂、小斉の湯はいくつか露天風呂があるが、そのうちの「見晴らしの湯」へ入った。
こちらも誰も入っていなかったので独占できてしまった。 f:id:hkou:20161105124406j:plain

紅葉が真横にあって、温泉に反射してなかなか良い f:id:hkou:20161105124412j:plain

ここの露天風呂は標高1257メートルにあり、温泉に浸かりながら蓼科高原を一望することできる。 f:id:hkou:20161105124419j:plain

伊豆ツーリング

1日目

朝起きるのが遅くて通勤ラッシュに巻き込まれそうになったのでやむなく高速道路を使った。高速道路も名古屋を抜けるまでは混んでいたけど新東名に入ると殆ど車が無くなって走りやすくてよい。

f:id:hkou:20160909094419j:plain

朝ごはんはNEOPASA岡崎の伊藤和四五郎商店でたまごかけごはんを頼んだ。新東名のSAはやっぱり新しいだけあって非常に綺麗

f:id:hkou:20160909082820j:plain

高速道路走ってある程度距離を稼ぐことが出来たので途中で高速を降りて下道を走ることにした。久しぶりに国道1号線沿いの「道の駅富士」でしらすを食べたくなりお昼ごはんはここで食べた。 f:id:hkou:20160909122653j:plain

湯ヶ島温泉 河鹿の湯

すこし高速降りた場所が手前過ぎたみたいで最初の温泉に着いたのが遅くなってしまった。本当は湯ヶ島温泉は別のところへ行きたかったのだけれど、すでに日帰り入浴の時間が過ぎてしまっていて入れなかったので、近くの河鹿の湯に入った。
こじんまりとした湯船で2〜3人入ると窮屈になるだろう。温度は熱めで長くは入っていられなかったが、長時間の運転で疲れていたので逆にそれが気持ちよかった。

f:id:hkou:20160909143556j:plain

f:id:hkou:20160909143543j:plain

熱川温泉 高磯の湯

海岸線沿いにある温泉。プールも併設されているがわたしが行った時は水が抜かれていた。温泉に浸かりながら太平洋が一望できる。この辺りは波が強いみたいでテトラポッドにぶつかった波の轟音が間近で聞こえてくる。

f:id:hkou:20160909155822j:plain

f:id:hkou:20160909160248j:plain

f:id:hkou:20160909163000j:plain

大川露天風呂 磯の湯

熱川温泉 高磯の湯から海岸線沿いを走って15分程度のところに磯の湯がある。ここも海を一望できる温泉だ。伊豆の温泉は無色透明なものが多いがここは珍しくにごり湯になっており一番温泉らしさを感じた。

f:id:hkou:20160909171536j:plain

にごり湯 f:id:hkou:20160909165232j:plain

太平洋が一望できる。ここはそこまで波が無かったので静かだった。 f:id:hkou:20160909165037j:plain

2日目

伊豆を抜けて富士山の近くの「ふもとっぱら」というキャンプ場に泊まった。このキャンプ場は富士山が一望できると聞いていたので朝起きた時に富士山を眺められることを楽しみにしていたが丁度逆光になる位置だったのでうまく写真が撮れなかった。

f:id:hkou:20160910074104j:plain

早朝は霧がかかっていて何か神秘的な光景だった。 f:id:hkou:20160910055324j:plain

ほったらかし温泉

近かったので久しぶりにほったらかし温泉へ寄った。山の上にある温泉なので何年か前に行った時は携帯が圏外になっていたが今は普通に繋がっているので普通にネットができた。
何度か行ってる温泉なのでそこまで目新しいことはないが、結構有名な温泉なので観光客が多くてすこし辟易とした。

f:id:hkou:20160910101431j:plain

前回行った時は「こっちの湯」へ入ったので今回は「あっちの湯」へ入った。

f:id:hkou:20160910101437j:plain

能登&金沢ツーリング

ふとツーリングしたくなったので前々から行きたかった能登方面へ行ってみた。

1日目

千里浜なぎさドライブウェイ

車で走ることができる砂浜として有名。砂粒が均一だからタイヤがスタックせずに走れるそうだ。確かに走ってみると通常のオフロードよりも走りやすい。ただところどころ自動車が付けたタイヤの轍でハンドルが取られそうになって怖い。あと湿った地面だとある程度固まってて走りやすいけど乾いた地面は完全に砂状になっていてここもハンドルが取られて怖かった。

f:id:hkou:20160903104321j:plain

f:id:hkou:20160903104651j:plain

バスも普通に走っていく。 f:id:hkou:20160903105852j:plain

禄剛埼灯台能登半島最先端)

能登半島の最先端らしい。バイクでは直接行くことは出来ない。「道の駅 狼煙」にバイクを停めておいて少し小高い山を徒歩で登った。

f:id:hkou:20160903140542j:plain

快晴だったので日本海がよく見えて綺麗だった。

f:id:hkou:20160903140617j:plain

なかじま猿田彦温泉 いやしの湯

最先端登って汗をかいたので温泉に入ることにした。浴室から海が一望できて良い感じ。 f:id:hkou:20160903163139j:plain

2日目

2日目も快晴に恵まれた。ツイてる。 f:id:hkou:20160904094430j:plain

道の駅 越前

海鮮丼。越前はカニが有名らしく、海鮮丼にしては珍しくカニがまるごと入っている。正直むいて出して欲しかった…手をベタベタにしながら食べなきゃいけないから。 f:id:hkou:20160904103825j:plain

越前温泉 露天風呂 漁火

道の駅越前に併設された温泉。露天風呂から下の写真みたいな海が一望できる(下の写真は風呂から写真撮れなかったので道の駅の横から海を撮ったもの)。入浴料510円。こんな絶景が見えるのに人がまばらで気楽に入浴できて良かった。おすすめスポット。 f:id:hkou:20160904110502j:plain

仕事が終わりました。あと読んだ本の整理

8月末をもって入社してからずっと携わっていた仕事が終わることになった。
約1年半ぐらいになるのだろうか、それなりに長いので終わった時はすこし感慨深いものを感じた。
この1年半は今までの人生の中で一番技術書を読んだような気がする。何せ仕事で利用する言語、ツール、ライブラリ、etc…がほぼ初めてなものばかりで、「まず、これは何なのか?」ってところからスタートするのが常だった。また基礎的な知識もかなり欠けていることも分かった。もっと学ばなければという意欲がとても湧いた1年半でした。
備忘録として読んだ本を並べてみよう。

Scala(または関数型プログラミング?)

Scalaで実装する仕事をすることになったのだが、Better Java的なコードしか書いてこなかったので、より良いコードを書くために読んだ本。

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版

Scala関数型デザイン&プログラミング―Scalazコントリビューターによる関数型徹底ガイド

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

UX

自社サービスのUXを考えよう→そもそもUXとは何だ?ってことで読んだ本

一人から始めるユーザーエクスペリエンス

一人から始めるユーザーエクスペリエンス

一人から始めるユーザーエクスペリエンス

プロジェクトマネジメント、組織論

銀の弾丸を探そうとしたが、なかなか見つからないもんだ…

SCRUM BOOT CAMP THE BOOK

SCRUM BOOT CAMP THE BOOK

SCRUM BOOT CAMP THE BOOK

ユーザーストーリーマッピング

ユーザーストーリーマッピング

ユーザーストーリーマッピング

アジャイルな見積と計画

アート・オブ・プロジェクトマネジメント ―マイクロソフトで培われた実践手法

アート・オブ・プロジェクトマネジメント ―マイクロソフトで培われた実践手法 (THEORY/IN/PRACTICE)

アート・オブ・プロジェクトマネジメント ―マイクロソフトで培われた実践手法 (THEORY/IN/PRACTICE)

カンバン: ソフトウェア開発の変革

カンバン: ソフトウェア開発の変革

カンバン: ソフトウェア開発の変革

スクラム 仕事が4倍速くなる“世界標準”のチーム戦術 (早川書房)

インフラ

お仕事でインフラ、運用管理周りをやることになったので読んだ本

インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門

インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門

インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門

実践 パケット解析 第2版 ―Wiresharkを使ったトラブルシューティング

実践 パケット解析 第2版 ―Wiresharkを使ったトラブルシューティング

実践 パケット解析 第2版 ―Wiresharkを使ったトラブルシューティング

基礎からわかるTCP/IP ネットワークコンピューティング入門

Hinemos 統合管理[実践]入門 Software Design Plus

Hinemos統合管理[実践]入門 (Software Design plus)

Hinemos統合管理[実践]入門 (Software Design plus)

リモートワーク

リモートワークに興味が出てきた時に読んでた本、リモートワークの利点、欠点は何があるのかを知ろうと思い読んでいた。

強いチームはオフィスを捨てる

強いチームはオフィスを捨てる: 37シグナルズが考える「働き方革命」

強いチームはオフィスを捨てる: 37シグナルズが考える「働き方革命」

マイクロソフトを辞めて、オフィスのない会社で働いてみた

マイクロソフトを辞めて、オフィスのない会社で働いてみた

マイクロソフトを辞めて、オフィスのない会社で働いてみた

フロント

AngularJSアプリケーション開発ガイド

AngularJSアプリケーション開発ガイド

AngularJSアプリケーション開発ガイド

Windows Presentation Foundationプログラミング

Windows Presentation Foundationプログラミング

Windows Presentation Foundationプログラミング

Haxeプログラミング入門―1つのプログラムから、いろいろな言語に自動変換!

Haxeプログラミング入門―1つのプログラムから、いろいろな言語に自動変換! (I・O BOOKS)

Haxeプログラミング入門―1つのプログラムから、いろいろな言語に自動変換! (I・O BOOKS)

並行並列

Java並行処理プログラミング ―その「基盤」と「最新API」を究める

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―

C#によるマルチコアのための非同期/並列処理プログラミング

Haskellによる並列・並行プログラミング

Haskellによる並列・並行プログラミング

Haskellによる並列・並行プログラミング

数学

技術書とか実用書ばかり読んでると飽きてくるのでたまに軽めの数学本が読みたくなってくる。

グッド・マス : ギークのための数・論理・計算機科学

グッド・マス ギークのための数・論理・計算機科学

グッド・マス ギークのための数・論理・計算機科学

数学ガールの秘密ノート/微分を追いかけて

数学ガールの秘密ノート/微分を追いかけて

数学ガールの秘密ノート/微分を追いかけて

英語

米国行って自分の英語力のなさを自覚したあげく一念発起して勉強したものの継続はしてないなぁ…。

DUO 3.0

DUO 3.0

DUO 3.0

APIデザインの極意 Java/NetBeansアーキテクト探究ノート

会計

仕事が途切れて会計っぽい仕事やる機運が高まっていた時期があり、予習として勉強していた。

SEがはじめて学ぶ会計

SEがはじめて学ぶ会計

SEがはじめて学ぶ会計

合格テキスト 日商簿記3級Ver.6.0 (よくわかる簿記シリーズ)

合格テキスト 日商簿記3級Ver.6.0 (よくわかる簿記シリーズ)

合格テキスト 日商簿記3級Ver.6.0 (よくわかる簿記シリーズ)

その他

21世紀の貨幣論

21世紀の貨幣論

21世紀の貨幣論

自己信頼[新訳]

自己信頼[新訳]

自己信頼[新訳]

数学文章作法 基礎編 (ちくま学芸文庫)

数学文章作法 基礎編 (ちくま学芸文庫)

数学文章作法 基礎編 (ちくま学芸文庫)

世界一やさしい問題解決の授業―自分で考え、行動する力が身につく

世界一やさしい問題解決の授業―自分で考え、行動する力が身につく

世界一やさしい問題解決の授業―自分で考え、行動する力が身につく

マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャ

Web API: The Good Parts

Web API: The Good Parts

Web API: The Good Parts

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

パケットキャプチャを作ってみる

概要

最近、仕事でインフラ周りを見ているのだが、突然コネクションが切れるという問題が発生し、Wiresharkを使ってパケットキャプチャし原因を調査していた。そこで思いの外ネットワークの基礎知識が忘れかけていたので、ネットワークの復習も兼ねてパケットキャプチャを自作してみることにした。

まず考えるのはネットワークインタフェースへのアクセス方法だが調べたところ以下の2種類があるようだ。

  • Socket (RAW)
  • BPF (Berkeley Packet Filter)

SocketはL4(トランスポートレイヤー)は簡単にアクセスできたが、もう少し低レイヤーから触ってみたかったので、PF_PACKETアドレスファミリを指定してRAW Socketを作ってみたがパケットを取得することができない。どうもMac OS XBSD)はraw socketは許可されてないようでlibpcap使うか、BPF (Berkeley Packet Filter)を使用するしかないらしい。なのでBPFでパケットキャプチャを作ることにした。

stackoverflow.com

BPFについて

BPFの概要図

f:id:hkou:20160827130441p:plain

BPFは主要な機能は以下の2つ

実際にプログラムからデータリンク層にアクセスするには「/dev/bpf#」というファイルを開いて読み込む。
BPFの詳細、設計思想等については以下の論文が参考になる。

http://www.tcpdump.org/papers/bpf-usenix93.pdf

bpfのOpen

「/dev/bpf#」というファイルを開く、末尾に数値を付加して順番に開けるファイルを探す。

char buf[11] = {0};
int bpf = 0;
    
for (int i = 0; i < 99; ++i) {
    sprintf(buf, "/dev/bpf%i", i);
    bpf = open(buf, O_RDWR);
        
    if (bpf != -1) break;
}
printf("open %s\n", buf);

ネットワークインタフェースに紐付ける

ioctl システムコールでBIOCSETIFを指定し「en0」のネットワークインタフェースに紐付ける。

struct ifreq interface;
strcpy(interface.ifr_name, "en0");
if(ioctl(bpf, BIOCSETIF, &interface) > 0) {
    perror("ioctl BIOCSETIF");
    return errno;
}

Man page of IOCTL

プロミスキャスモードにする

すべてのパケットが拾えるようにプロミスキャスモードに指定する。

if (ioctl(bpf, BIOCPROMISC, NULL) == -1) {
    perror("ioctl BIOCPROMISC");
    return errno;
}

パケットの読み込み

BPF Bufferの構造

BPFからパケットを読み込む際に注意しなければならないのはバッファから読み込んだ場合、複数パケット含まれていることを考慮しなければならない。

f:id:hkou:20160827173503p:plain

BPF Buffer自体のサイズは ioctl システムコールでBIOCGBLENを指定し呼び出すことで取得することができる。

int bufLength = 1;
// BIOCGBLEN : 受信バッファの必要サイズ
if (ioctl(bpf, BIOCGBLEN, &bufLength) == -1) {
    perror("ioctl BIOCGBLEN");
    return errno;
}

BPFパケットの分割

BPFBufferからデータを取得したらパケット毎に分割する。
分割にはBPF Headerの情報を読み込んで「bh_hdrlen」と「bh_caplen」を足し合わせたサイズ分ポインタを進める。
ポインタを進める際にBPF_WORDALIGNマクロを利用するとワード境界を考慮したパディング分のサイズを付加してくれる。

ptr += BPF_WORDALIGN(bpfPacket->bh_hdrlen + bpfPacket->bh_caplen);
struct bpf_hdr {
        struct timeval bh_tstamp;     /* タイムスタンプ */
        u_long bh_caplen;             /* キャプチャされた部分の長さ */
        u_long bh_datalen;            /* パケットのオリジナルの長さ */
        u_short bh_hdrlen;            /* bpf ヘッダの長さ (この構造体+ 境界調整パディング) */
};

Ethernet Frameの取得

BPFBufferからBPFパケットに分割したらPayload部分がEthernet Frameになっている。
BPF Headerのサイズ分ポインタを進めて以下のEthernetHeaderにマッピングして取得する。

typedef struct {
    // 送信先Macアドレス
    unsigned char destAddress[6];
    // 送信元Macアドレス
    unsigned char srcAddress[6];
    // 種類
    unsigned short type;
} EthernetHeader;

IP Frameの取得

Ethernet Headerのtypeが0x0800になっているパケットがIPフレームである。
Ethernet Headerのサイズ分ポインタを進めて 以下のIPHeaderにマッピングして取得する。

typedef struct {
// リトルエンディアン 
    unsigned char headerLength: 4;
    unsigned char version: 4;

// ビッグエンディアン
//    unsigned char version: 4;
//    unsigned char headerLength: 4;

    // サービスタイプ(IPパケットの優先度)
    unsigned char tos;
    // IPパケット全体のサイズをbyte単位で数えたもの
    unsigned short totalLength;
    // IPフラグメンテーション用
    unsigned short id;
    
    unsigned short fragment;
    // Time to Live
    unsigned char ttl;
    // プロトコル番号
    unsigned char protocol;
    // チェックサム
    unsigned short checkSum;
    // 送信元IPアドレス
    unsigned char srcAddress[4];
    // 送信先IPアドレス
    unsigned char destAddress[4];
    
    IpOption option;
} IpHeader;

TCP Frameの取得

IpHeaderのprotocolが0x06になっているパケットがTCPフレームである。
IPヘッダのサイズはオプションが可変なのでヘッダサイズも可変である。そのため単純な固定値では計算できず「headerLength」プロパティを参照する必要がある。
「headerLength」プロパティは単位が32bitなので実際にポインタを進める際にはヘッダサイズを4倍する。
上記の計算で求めたサイズ分ポインタを進めて 以下のTCPHeaderにマッピングして取得する。

typedef struct {
    // 送信元ポート番号
    unsigned short srcPort;
    // 宛先ポート番号
    unsigned short destPort;
    // シーケンス番号
    unsigned int sequenceNum;
    // 確認応答番号
    unsigned int acknowledgmentNum;
    // ヘッダ長
    unsigned int header: 4;
    // 予約済み
    unsigned int reserved: 6;
    
    // コードビット
    struct CodeBit {
        // 緊急フラグ
        unsigned int urg: 1;
        // ack
        unsigned int ack: 1;
        // Push(1:バッファリングしない)
        unsigned int psh: 1;
        // TCP 接続リセット
        unsigned int rst: 1;
        // synchronize
        unsigned int syn: 1;
        // tcp接続終了
        unsigned int fin: 1;
    } codeBit;
    
    // ウィンドウサイズ
    unsigned short windowSize;
    
    // チェックサム
    unsigned short checkSum;
    
    // 緊急ポインタ
    unsigned short urgentPointer;
} TCPHeader;

完成品

とりあえず作ってみた版のパケットキャプチャツール
全フィールドチェックしてないので構造体のアライメントのバグとかあるような気がする。

github.com

参考にしたページ

BPFとLinuxでのL2IFを扱うネットワークプログラミングでの違いについて – Slank Blog

kaworu.jpn.org

DockerでさくっとRabbitMQ3.6.2の検証環境を作る

RabbitMQ3.6.2の動作検証がしたくなったので環境用意しようとしたがめんどくさくなったのでDockerで環境作ることにした。

準備

自宅のMacにはDockerが入ってないのでインストールから始める。
Docker Tool BoxをDownloadしてインストーラにしたがってポチポチ進めていけば完了する。

https://www.docker.com/products/docker-toolbox

Docker QuickStart Terminalを立ち上げる

アプリケーションの下にDocker/Docker Quickstart Terminalのアイコンがあるので起動する。
ターミナルの画面が出てくる。

Docker run

DockerHubにRabbitMQのOfficial Imageがあったのでこれを使う。
https://hub.docker.com/_/rabbitmq/

Management Pluginも使いたいので「3-management」タグのイメージを使う。
ポートフォワードはゲストとホストを同じポート番号にする。

Docker Quickstart Terminal上で以下のコマンド実行

docker run -p 15672:15672 -p 5672:5672 rabbitmq:3-management

動作確認

Web管理ツールにアクセスするためにboot2dockerのIPアドレスを確認する。

docker-machine ip         
192.168.99.100

先ほどのIPにポート付けてブラウザでアクセスする。
ちゃんとアクセスできた。
f:id:hkou:20160605155736p:plain

めんどうな環境構築が10分程度で済んだ。すごい

その他

起動中のコンテナ一覧を表示する

docker ps

全てのコンテナの一覧を表示する

docker ps -a

起動中のコンテナを停止する

docker stop <コンテナIDかコンテナ名>

コンテナを再度立ち上げる

docker start <コンテナIDかコンテナ名>

イメージの一覧を表示する

docker images

RabbitMQメモ

対象

  • RabbitMQ 3.6.2
    • AMQP 0-9-1

RabbitMQを構成するもの

  • Publisher
    • メッセージを送信するアプリケーション
  • MessageBroker(RabbitMQ)
    • メッセージを仲介する
  • VirtualHost
    • ExchangeやQueueをグループ分けする
  • Exchange
    • Publisherから受け取ったメッセージをBindingの設定に従ってQueueに配送する。
  • Queue
    • Exchangeから配送されてきたメッセージの保管場所

f:id:hkou:20160603230533p:plain

Exchangeの種類

参考: RabbitMQ - AMQP 0-9-1 Model Explained

Fanout

ExchangeにBindしているQueue全てにメッセージを配送する。

Direct

メッセージに含まれるrouting keyとBindingに含まれる routing keyが一致したQueueにメッセージを配送する。

Topic

Direct Exchangeと同じようにrouting keyとBindingのrouting keyを比較するが以下の特徴がある。

  • routing keyは「.」(ドット)で句切られた単語のリストでなければならない
  • Bindingのrouting keyにワイルドカード(のようなもの)が使用できる。
    • 「*」一つの単語に置き換える
    • 「#」0以上の単語に置き換える

Headers

メッセージに含まれるheaderとBinding argumentを比較し一致したQueueにメッセージを配送する。

  • 「x-match:all」headerの完全一致
  • 「x-match:any」headerの部分一致

Exchangeの属性

  • Durability(耐久性)
    • RabbitMQを再起動しても存続するかどうか
  • Auto-Delete
    • 全てのBindingが無くなった時に削除するかどうか

Queueの属性

  • Durability(耐久性)
    • RabbitMQを再起動しても存続するかどうか
  • Exclusive(排他性)
    • 一つだけの接続で使用され、その接続が切断された時にキューが削除される
  • Auto-Delete
    • 全てのConsumerが登録解除した時に削除する

Messageの属性

  • Content type
  • Content encoding
  • Routing Key
  • Delivery mode
    • persistent (永続的)かどうか、RabbitMQを再起動しても存続する
  • Message Priority
  • Message publishing timestamp
  • Expiration period(有効期限)
  • Publisher application id

参考

AMQP 0-9-1 Model Explained RabbitMQ - AMQP 0-9-1 Model Explained

AMQP 0-9-1 Complete Reference Guide https://www.rabbitmq.com/amqp-0-9-1-reference.html