能登&金沢ツーリング

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

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

九州温泉巡りツーリング

GWを10連休にして九州巡りツーリングしてきた。いつものように温泉巡りメインの旅行です。 温泉巡りを各地でしてきたけど温泉の名所であるところの別府にはまだ言ってないねという話しから、じゃあ今度のGWに九州行くかということになった。今回は移動の自由度を上げるために宿泊はキャンプで済ませることにした。その分バイクに積載する荷物が多くなったので色々運転しづらくなったけど。 f:id:hkou:20160429132501j:plain

今回巡った温泉

久瀬温泉 白龍の湯

琵琶湖まで向かう道すがらに入った温泉。大人410円。大通りから脇道にそれて結構深く行ったところにあるので空いていて良かった。しかし他のお客さんが居たので湯船の写真は撮れず。 f:id:hkou:20160429101221j:plain

フェリーさんふらわあ内の風呂

※写真なし
温泉ではなくただのでかい風呂だけど。窓が付いているので外の大海原が一望できる(朝風呂がオススメです)船内なので地味に揺れてます。

↓お風呂に入りながらこんな感じの景色が一望できます。 f:id:hkou:20160501060626j:plain

竹瓦温泉

別府で最初に入った温泉。明治12年(1879)創設されたすごく古い温泉。設備に歴史を感じます。

f:id:hkou:20160501091950j:plain

別府駅の観光案内所で買ったスパポート。別府市内の温泉入るときにこれを出してハンコ押してもらい、8個毎にハンコが貯まると段位認定してくれるらしいです。 f:id:hkou:20160501100337j:plain

別府温泉保養ランド

ここはかねてから行ってみたかった場所の一つ。泥湯で有名なところです。肌がつるつるになるらしいのですが確かに温泉から出た後は心なしか肌がつるつるしたような気がします。温泉内の立て看板に「泥を顔に塗らないでください」みたいなものがありましたがあれは守ったほうがいいです。痛い目見ます(見ました…) f:id:hkou:20160501104337j:plain

ひょうたん温泉

別府の温泉。スパ銭みたいな感じです。人がたくさん居るので私はあんまりこういう感じのところは好きではないですが温泉は源泉使っているのでそこは良かったです。 f:id:hkou:20160501203240j:plain

別府海浜砂湯

砂湯というものがどういうものか知りたくて試しに入ってみたところ。他のところでも砂湯はあるんですけど海辺で開放感があるのはここだけっぽいです。入る時間が15分と決まっていて最初は短いなと思ってたけど実際入ってみると…うん…10分ぐらいで充分です。

馬子草温泉きづな

別府から離れ長崎へ向かう道中に入った温泉。鉄泉で何よりも人が誰もいなくて貸し切り状態なのが良かった。 f:id:hkou:20160502135215j:plain

周りが牧草になってて露天風呂からの景色もいいです。 f:id:hkou:20160502135227j:plain

壁湯温泉

川の直ぐ側にある温泉。ここも人が居なくて貸し切り状態なので良かったです。 f:id:hkou:20160502151115j:plain

天然の湯 あおき温泉

※写真なし 普通の街なかにある銭湯みたいな外観と内観、完全に地元民向けの温泉ですね。ただし泉質がかなり良くてぬるっとしてます。

霧島温泉郷 野々湯温泉

キャンプ場横にあった温泉。夜と朝の2回入りました。 f:id:hkou:20160506064535j:plain

さくらじま 白浜温泉センター

※写真なし 桜島にある温泉。ここも完全に地元民向けの温泉施設。しかしちゃんと源泉使っているみたいでお湯はなかな良かったです。

釈迦の隠し湯 三休の湯

帰り道に寄っていった温泉。三重県にあります。実はここ一度尋ねたことがあったのですがその時はお休みで4月から営業とあったので丁度近くを通るんだしということで寄ることにしました。ここは人が少ないし、景色も良いのでお薦めですね f:id:hkou:20160507125651j:plain f:id:hkou:20160507131548j:plain